생성자는 어떨때 쓰는 것일까?
기본적으로 생성자는 인스턴스를 생성할때 쓰지만, 다형성에도 주로 이용한다.
class Coffee {
int price;
public Coffee(int price) {
this.price = price;
}
}
class Americano extends Coffee { <------------(1)
public Americano() {
super(4000); // 상위 클래스 Coffee의 생성자를 호출
}
public String toString() {
return "아메리카노";
} //Object클래스 toString()메서드 오버라이딩
}
class CaffeLatte extends Coffee {
public CaffeLatte() {
super(5000);
}
public String toString() {
return "카페라떼";
}
}
--------------------------------------------------------------------------
class Customer {
int money = 50000;
void buyCoffee(Coffee coffee) {
if (money < coffee.price) { // 물건 가격보다 돈이 없는 경우
System.out.println("잔액이 부족합니다.");
return;
}
money = money - coffee.price; // 가진 돈 - 커피 가격
System.out.println(coffee + "를 구입했습니다.");
}
}
- (1)에 보면
super(4000);으로 상위클래스 Coffee의 생성자를 호출하고 있다.- Coffee 클래스의 필드값 price는 설계상 하위클래스에의해 계속해서 그 값이 변해야하는 구조로 되어있다.
- 이럴 때 super() 를 이용한 다형성을 이용한다.
- 따라서 다형성을 통해
Coffee.price코드만으로 여러가지 값을 나타낼 수 있게 된다.
public class PolymorphismEx {
public static void main(String[] args) {
Customer customer = new Customer();
customer.buyCoffee(new Americano());
customer.buyCoffee(new CaffeLatte());
System.out.println("현재 잔액은 " + customer.money + "원 입니다.");
}
}
buyCoffee메서드는 참조변수로 Coffee coffee를 받고있다.
따라서customer.buyCoffee(new Americano());의 괄호안을 풀어쓰면 다음과같다
Coffee coffee = new Americano()이는 하위 클래스인 Americano가 상위클래스타입인 Coffee의 참조변수로 할당되고있는것을 뜻한다.- 즉, Americano입장에서는 사용할 수 있는 멤버가 줄어들게되지만 공통적인 값 price를 CaffeLatte 클래스와 공유할 수있어서 설계면에서는 훨신 효율 이좋아지게 된다.
- Customer 클래스입장에서 살펴보면 메서드의 모든 참조변수를 Coffee 클래스로 받고있기때문에 변경이 필요하지 않고
- 호출시 Customer 클래스를 상속받는 Americano와 CaffeLatte 클래스만 참조변수에 할당시켜주면 된다.