[JAVA] 객체 배열...
오늘 학원에서 풀었던 클래스챕터의 마지막 문제입니다.
저에게는 매우 어려운 문제였고, 강사님이 작성하신 코드를 리뷰해보아도 모르는게 있었습니다.
제가 이해하기 어려웠던 부분이 클래스를 배열로 바꾸었다는 점입니다.
강사님 코드를 리뷰해보자면,
Account[] accounts = new Account[100];
main클래스의 앞부분에 Account라는 클래스로 길이가 100인 배열 객체를 만들었습니다.
여기까지는 저도 만들었던 부분이라 이해가 갔는데, 갑자기
Account account = new Account(); 라는 새로운 객체를 만들더니
여기에 Account클래스의 필드값을 가져오고는 앞서 만들었던 배열 객체(?)에 대입을 해버립니다!!
이렇게 말이죠. accounts[numberOfAccount] = account;
Account[] accounts = new Account[100];
Account account = new Account();
account.setNumber(accountNumber);
account.setName(accountName);
account.setBalance(balance);
accounts[numberOfAccount] = account;
numberOfAccount++;
클래스가 배열이 될 수 있다는것이 의아해서
(배열엔 같은 타입만 담을 수 있는게 아닌가요?)
구글에 '클래스를 배열로' 라고 검색하니 자동검색어로 '자바 클래스를 배열로'가 뜹니다.
뭔가 규칙이 있나봅니다.
"객체 배열"이라는 키워드가 있어 찾아봤습니다.

클래스를 배열로 선언하는 것이 가능하고,
다양한 타입의 데이터를 표현할 때 객체 배열을 통해 저장할 수 있다고 합니다.
Book 객체 3개를 배열 형태로 만들어 사용하기 위해서 먼저 아래와 같이 코드를 작성하게 되면,
레퍼런스 변수 b와 Book 객체에 대한 레퍼런스 변수 3개가 생성됩니다.
Book[ ] b = new Book[3];
이렇게 선언하게 되면 Book 객체를 담을 레퍼런스 변수 3개가 배열형태로 생성됩니다.
주의할 점은 아직 Book 객체가 만들어진것은 아니기 때문에, Book 객체를 사용하기 위해서는 아래와 같이 Book 객체를 생성해 주어야 합니다.
b[1] = new Book( );
b[2] = new Book( );
b[3] = new Book( );
위와 같이 객체 배열 생성 코드를 작성하게 되면 위의 그림과 같이 메모리상에 변수들이 할당됩니다.
출처: https://kadosholy.tistory.com/90 [KADOSHoly:티스토리]
- 객체 배열의 정의: 자바에서 배열은 동일한 타입의 여러 변수를 하나의 묶음으로 다루는 것을 의미합니다. 그 중에서 객체 배열은 객체의 참조값을 요소로 가지는 배열입니다. 즉, 객체 배열은 여러 객체를 묶어서 한 번에 관리하게 해주는 도구입니다.
- 객체 배열의 선언과 할당 방법: 객체 배열은 아래와 같이 선언하고 할당할 수 있습니다.
클래스타입[] 배열이름; // 선언
배열이름 = new 클래스타입[배열의 크기]; // 할당
예를 들어, Student 클래스의 객체를 저장하는 배열을 생성하려면 다음과 같이 합니다.
Student[] students; // 선언
students = new Student[10]; // 할당
- 사용 시의 주의점: 객체 배열을 생성했다고 해서 해당 배열에 자동으로 객체가 저장되는 것은 아닙니다. 배열에는 객체의 참조값이 저장되기 때문에, 각 배열의 요소마다 실제 객체를 생성해주는 과정이 필요합니다.
for(int i=0; i<students.length; i++) {
students[i] = new Student(); // 각 요소마다 객체 생성
}
- 객체 배열 생성 시 메모리의 변화: 객체 배열을 생성하면 힙 메모리 영역에 배열의 크기만큼의 공간이 할당됩니다. 그리고 각 배열의 요소마다 객체를 생성하면, 각 객체마다 별도의 메모리 공간이 할당되고, 배열의 각 요소는 생성된 객체를 참조하게 됩니다.
즉, 예를 들어 Student[10] 배열이 있다면 메모리 안에는 Student 객체를 참조할 수 있는 참조변수 10개가 연속적으로 생성되며, 각각의 참조변수는 new Student()로 생성된 실제 객체를 가리키게 됩니다.
이러한 특성 때문에, 객체 배열을 사용할 때는 반드시 각 배열의 요소마다 객체를 생성해주는 것을 잊지 말아야 합니다.
자바에서 배열은 동일한 타입의 데이터만 담을 수 있습니다. 다양한 타입의 필드값을 담으려면, 이를 포함하는 사용자 정의 클래스를 생성하고, 그 클래스의 객체 배열을 사용해야 합니다.
예를 들어, 아래와 같이 Person 클래스를 선언할 수 있습니다.
public class Person {
String name;
int age;
double height;
}
이제 Person 객체를 담는 배열을 생성하면, 이 배열의 각 요소는 name, age, height라는 서로 다른 타입의 필드값을 가질 수 있습니다.
Person[] people = new Person[10];
for(int i=0; i<people.length; i++) {
people[i] = new Person();
}
이렇게 하면 people[0].name, people[0].age, people[0].height와 같은 방식으로 다양한 타입의 필드값에 접근할 수 있습니다.
이제야 궁금증이 풀립니다.
여러 개의 객체를 묶어서 한번에 관리하는 객체 배열이라는것이 존재하고, 클래스의 객체 생성 후에 배열에 객체를 저장합니다.
아직 완벽히 이해가 된 것은 아니지만 어느정도는 알게 되었습니다. 앞으로 조금 더 공부하여 제것으로 만들어야겠습니다.
package ch06.exercise.p20;
public class Account {
private String number; // 계좌번호
private String name; // 계좌주 이름
private int balance; // 현재 잔액
public void setNumber(String number) {
this.number = number;
}
public void setName(String name) {
this.name = name;
}
public void setBalance(int balance) {
this.balance = balance;
}
public String getNumber() {
return number;
}
public String getName() {
return name;
}
public int getBalance() {
return balance;
}
}
package ch06.exercise.p20;
import java.util.Scanner;
public class BankApplication {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Account[] accounts = new Account[100];
int numberOfAccount = 0;
boolean run = true;
while (run) {
System.out.println("""
--------------------------------------
1.계좌생성|2.계좌목록|3.예금|4.출금|5.종료
--------------------------------------""");
System.out.print("선택>");
String menu = scanner.nextLine();
switch (menu) {
case "1" -> {
System.out.println("""
-------
계좌생성
------- """);
System.out.print("계좌번호: ");
String accountNumber = scanner.nextLine();
System.out.print("계좌주: ");
String accountName = scanner.nextLine();
System.out.print("초기입금액: ");
int balance = Integer.parseInt(scanner.nextLine());
Account account = new Account();
account.setNumber(accountNumber);
account.setName(accountName);
account.setBalance(balance);
accounts[numberOfAccount] = account;
numberOfAccount++;
System.out.println("결과: 계좌가 생성되었습니다.");
}
case "2" -> {
System.out.println("""
-------
계좌목록
------- """);
for (int i = 0; i < numberOfAccount; i++) {
System.out.println(STR."\{accounts[i].getNumber()} \{accounts[i].getName()} \{accounts[i].getBalance()}");
}
}
case "3" -> {
System.out.println("""
-------
예금
------- """);
System.out.print("계좌번호: ");
String accountNumber = scanner.nextLine();
System.out.print("예금액: ");
int deposit = Integer.parseInt(scanner.nextLine());
// 계좌번호가 accountNumber인 계좌 찾기
for (int i = 0; i < numberOfAccount; i++) {
if (accounts[i].getNumber().equals(accountNumber)) {
int balance = accounts[i].getBalance();
accounts[i].setBalance(balance + deposit);
}
}
}
case "4" -> {
System.out.println("""
-------
출금
------- """);
System.out.print("계좌번호: ");
String accountNumber = scanner.nextLine();
System.out.print("출금액: ");
int withdrawal = Integer.parseInt(scanner.nextLine());
// 계좌번호가 accountNumber인 계좌 찾기
for (int i = 0; i < numberOfAccount; i++) {
if (accounts[i].getNumber().equals(accountNumber)) {
int balance = accounts[i].getBalance();
accounts[i].setBalance(balance - withdrawal);
}
}
System.out.println("결과: 출금이 성공되었습니다.");
}
case "5" -> run = false;
}
}
System.out.println("프로그램 종료");
scanner.close();
}
}