Day 9: 클래스와 객체
객체지향 프로그래밍(OOP)에서 클래스는 설계도이고, 객체는 그 설계도로 만든 실제 사물입니다. 자동차 설계도(클래스)로 여러 대의 자동차(객체)를 만들 수 있는 것과 같습니다. Java는 순수 객체지향 언어로, 모든 코드가 클래스 안에 존재합니다.
클래스 정의와 객체 생성
필드(속성)와 메서드(행동)로 클래스를 설계합니다.
public class Student {
// 필드 (속성)
String name;
int age;
String major;
double gpa;
// 메서드 (행동)
void introduce() {
System.out.println("안녕하세요, " + name + "입니다.");
System.out.println("전공: " + major + ", GPA: " + gpa);
}
void study(String subject) {
System.out.println(name + "이(가) " + subject + "을(를) 공부합니다.");
}
boolean isPassing() {
return gpa >= 2.0;
}
public static void main(String[] args) {
// 객체 생성
Student student1 = new Student();
student1.name = "홍길동";
student1.age = 22;
student1.major = "컴퓨터공학";
student1.gpa = 3.8;
Student student2 = new Student();
student2.name = "김영희";
student2.age = 21;
student2.major = "경영학";
student2.gpa = 4.2;
student1.introduce();
student2.introduce();
student1.study("Java");
System.out.println("합격 여부: " + student1.isPassing());
}
}
생성자 (Constructor)
객체를 생성할 때 자동으로 호출되는 특수한 메서드입니다. 클래스 이름과 같고, 반환 타입이 없습니다.
public class BankAccount {
String owner;
String accountNumber;
long balance;
// 기본 생성자
BankAccount() {
this.owner = "미지정";
this.accountNumber = "000-000-000";
this.balance = 0;
}
// 매개변수 있는 생성자
BankAccount(String owner, String accountNumber) {
this.owner = owner;
this.accountNumber = accountNumber;
this.balance = 0;
}
// 모든 필드를 초기화하는 생성자
BankAccount(String owner, String accountNumber, long balance) {
this.owner = owner;
this.accountNumber = accountNumber;
this.balance = balance;
}
void deposit(long amount) {
if (amount > 0) {
balance += amount;
System.out.println(amount + "원 입금. 잔액: " + balance + "원");
}
}
void withdraw(long amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
System.out.println(amount + "원 출금. 잔액: " + balance + "원");
} else {
System.out.println("잔액 부족! 현재 잔액: " + balance + "원");
}
}
void showInfo() {
System.out.println("[" + accountNumber + "] " + owner + " - 잔액: " + balance + "원");
}
public static void main(String[] args) {
BankAccount acc1 = new BankAccount();
BankAccount acc2 = new BankAccount("홍길동", "110-234-5678");
BankAccount acc3 = new BankAccount("김영희", "110-987-6543", 1000000);
acc2.deposit(500000);
acc2.withdraw(200000);
acc2.showInfo();
acc3.showInfo();
}
}
this 키워드와 메서드 체이닝
this는 현재 객체 자신을 가리킵니다. 필드와 매개변수 이름이 같을 때 구분하거나, 메서드 체이닝 패턴에 사용합니다.
public class Pizza {
String size;
String dough;
boolean cheese;
boolean pepperoni;
boolean mushroom;
Pizza(String size) {
this.size = size;
this.dough = "기본";
this.cheese = false;
this.pepperoni = false;
this.mushroom = false;
}
// 메서드 체이닝: this를 반환하여 연속 호출 가능
Pizza setDough(String dough) {
this.dough = dough;
return this;
}
Pizza addCheese() {
this.cheese = true;
return this;
}
Pizza addPepperoni() {
this.pepperoni = true;
return this;
}
Pizza addMushroom() {
this.mushroom = true;
return this;
}
void describe() {
System.out.println("=== 피자 주문 ===");
System.out.println("크기: " + size);
System.out.println("도우: " + dough);
System.out.println("치즈: " + (cheese ? "추가" : "없음"));
System.out.println("페퍼로니: " + (pepperoni ? "추가" : "없음"));
System.out.println("버섯: " + (mushroom ? "추가" : "없음"));
}
public static void main(String[] args) {
// 메서드 체이닝으로 깔끔하게 설정
Pizza myPizza = new Pizza("라지")
.setDough("씬")
.addCheese()
.addPepperoni()
.addMushroom();
myPizza.describe();
}
}
정적 멤버 (static)
클래스 레벨에서 공유되는 필드와 메서드입니다. 객체를 만들지 않아도 사용할 수 있습니다.
public class Counter {
// static 필드: 모든 객체가 공유
static int totalCount = 0;
// 인스턴스 필드: 각 객체마다 별도
String name;
int id;
Counter(String name) {
this.name = name;
totalCount++;
this.id = totalCount;
}
// static 메서드: 클래스 이름으로 호출
static int getTotalCount() {
return totalCount;
}
// 인스턴스 메서드
void showInfo() {
System.out.println("ID: " + id + ", 이름: " + name);
}
public static void main(String[] args) {
System.out.println("총 개수: " + Counter.getTotalCount()); // 0
Counter c1 = new Counter("첫 번째");
Counter c2 = new Counter("두 번째");
Counter c3 = new Counter("세 번째");
c1.showInfo(); // ID: 1
c2.showInfo(); // ID: 2
c3.showInfo(); // ID: 3
System.out.println("총 개수: " + Counter.getTotalCount()); // 3
}
}
오늘의 연습문제
-
도서 관리:
Book클래스를 만드세요. 필드: 제목, 저자, 가격, ISBN. 생성자 오버로딩(2개 이상),showInfo()메서드,applyDiscount(int percent)메서드를 구현하세요. -
좌표 계산기:
Point클래스를 만드세요. 필드: x, y (double). 두 점 사이의 거리를 구하는distanceTo(Point other)메서드와, 중점을 반환하는midPoint(Point other)메서드를 구현하세요. -
사원 번호 자동 생성:
Employee클래스에서 static 변수를 사용하여 객체가 생성될 때마다 “EMP-001”, “EMP-002” 형식의 사원번호가 자동 부여되도록 구현하세요.