인스턴스 변수 vs 정적 변수
Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 87개 중 15번째.
지금까지 우리가 생성한 모든 필드는 특정 객체에 속합니다. 각 BankAccount는 고유한 balance를 가지며, 각 Product는 고유한 name을 가집니다. 이것들은 인스턴스 변수입니다. 즉, 클래스의 각 인스턴스마다 별도로 존재합니다.
하지만 모든 객체에서 공유되는 데이터가 필요하다면 어떻게 해야 할까요? 바로 이럴 때 정적 변수(클래스 변수라고도 함)가 사용됩니다. 정적 변수는 특정 객체가 아니라 클래스 자체에 속합니다.
public class Student {
private String name; // 인스턴스 변수 - 학생별로 고유함
private static int totalCount; // 정적 변수 - 모든 학생이 공유함
public Student(String name) {
this.name = name;
totalCount++; // 공유 카운터를 증가시킴
}
public static int getTotalCount() {
return totalCount;
}
}여러 명의 학생을 생성할 때, 각 학생은 자신만의 name을(를) 가지지만, 모두 동일한 totalCount를 공유합니다:
Student s1 = new Student("Alice");
Student s2 = new Student("Bob");
System.out.println(Student.getTotalCount()); // 출력: 2객체를 통해서가 아니라 클래스 이름(Student.getTotalCount())을 통해 정적 변수에 접근하는 방식에 주목하세요. 이는 정적 멤버가 인스턴스가 아닌 클래스에 속한다는 점을 강조합니다.
객체마다 다른 데이터(예: 학생의 이름)에는 인스턴스 변수를 사용하세요. 공유되어야 하는 데이터(예: 생성된 객체의 수 계산)에는 정적 변수를 사용하세요.
챌린지
쉬움인스턴스 변수와 정적(static) 변수를 사용하여 개별 도서의 상세 정보와 전체 컬렉션의 총 도서 수를 추적하는 Book 재고 시스템을 구축해 보겠습니다.
코드를 구성하기 위해 두 개의 파일을 생성합니다:
Book.java: 개별 도서 정보를 추적하는 동시에 생성된 모든 도서의 수를 유지하는 Book 클래스를 생성합니다:- 인스턴스 변수
title(String) - 각 도서마다 고유함 - 인스턴스 변수
price(double) - 각 도서마다 고유함 - 정적 변수
totalBooks(int) - 모든 Book 객체 간에 공유되며, 생성된 도서의 총 개수를 추적함 - 제목과 가격을 매개변수로 받아 도서 총 개수를 증가시키는 생성자
- 제목을 위한 게터
getTitle() - 가격을 위한 게터
getPrice() - 생성된 도서의 총 개수를 반환하는 정적 메서드
getTotalBooks()
- 인스턴스 변수
Main.java: 여러 개의 Book 객체를 생성하고 정적 카운터가 모든 인스턴스를 어떻게 추적하는지 보여줍니다. 세 개의 도서 제목과 세 개의 가격을 입력으로 받습니다. 세 권의 도서를 모두 생성한 후, 다음 네 줄을 출력합니다:- 각 도서의 제목과 가격을
[title]: $[price]형식으로 출력 (가격은 소수점 둘째 자리까지 표시) - 정적 메서드를 사용한 총 도서 수:
Total books: [count]
- 각 도서의 제목과 가격을
title1, price1, title2, price2, title3, price3 순서로 총 6개의 입력을 받게 됩니다.
정적 메서드는 객체 인스턴스가 아닌 클래스 이름(Book.getTotalBooks())을 통해 접근해야 함을 기억하세요. 가격 형식을 지정할 때는 String.format("%.2f", price)를 사용하세요.
치트 시트
정적 변수(클래스 변수라고도 함)는 클래스 자체에 속하며, 각 객체마다 고유한 인스턴스 변수와 달리 해당 클래스의 모든 인스턴스에서 공유됩니다.
static 키워드를 사용하여 정적 변수를 선언합니다:
public class Student {
private String name; // 인스턴스 변수 - 학생마다 고유함
private static int totalCount; // 정적 변수 - 모든 학생이 공유함
public Student(String name) {
this.name = name;
totalCount++; // 공유 카운터를 증가시킴
}
public static int getTotalCount() {
return totalCount;
}
}객체 인스턴스가 아닌 클래스 이름을 통해 정적 변수와 메서드에 접근하세요:
Student s1 = new Student("Alice");
Student s2 = new Student("Bob");
System.out.println(Student.getTotalCount()); // 출력: 2객체마다 다른 데이터에는 인스턴스 변수를 사용하세요. 모든 인스턴스에서 공유되어야 하는 데이터에는 정적 변수를 사용하세요.
직접 해보기
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 세 권의 책에 대한 입력 읽기
String title1 = scanner.nextLine();
double price1 = Double.parseDouble(scanner.nextLine());
String title2 = scanner.nextLine();
double price2 = Double.parseDouble(scanner.nextLine());
String title3 = scanner.nextLine();
double price3 = Double.parseDouble(scanner.nextLine());
// TODO: 위에서 입력받은 값들을 사용하여 세 개의 Book 객체 생성
// TODO: 각 책의 제목과 가격을 [title]: $[price] 형식으로 출력
// 가격의 소수점 둘째 자리까지 형식을 맞추기 위해 String.format("%.2f", price)를 사용하세요
// TODO: static 메서드를 사용하여 전체 책의 권수를 출력
// 형식: Total books: [count]
// static 메서드는 클래스 이름인 Book.getTotalBooks()를 통해 접근해야 함을 기억하세요
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
4상속
상속의 기초 (extends)super 키워드메서드 오버라이딩 (@Override)생성자 체이닝Object 클래스단일 및 다중 레벨 상속다중 클래스 상속이 불가능한 이유요약 - 직원 계층 구조