본문 바로가기
개발공부/Java

[Java] 15. 상속에서 클래스 생성과 형 변환

by sangyeon 2022. 1. 24.
728x90

1. 하위 클래스가 생성되는 과정

- 하위 클래스를 생성하면 상위 클래스가 먼저 생성 됨

- new VIPCustomer()를 호출하면 그 상위 클래스인 Customer()가 먼저 호출 됨

- 클래스가 상속 받은 경우 하위 클래스의 생성자에서는 반드시 상위 클래스의 생성자를 호출한다.

 

 

2. Super 키워드

- 하위 클래스에서 가지는  상위 클래스에 대한 참조 값

- super()는 상위 클래스의 기본 생성자를 호출 함.

- 하위 클래스에서 명시적으로 상위 클래스의 생성자를 호출하지 않으면 super()가 호출 됨.

(*이때 반드시  상위 클래스에 기본 생성자가 존재해야 함*)

- 상위 클래스의 기본 생성자가 없는 경우 하위 클래스에서는 생성자에서 super를  이용해 명시적으로 상위 클래스의 생성자를 호출함.

- super는 생성된 상위 클래스 인스턴스의 참조 값을 가지므로 super를 이용하여 상위 클래스의 메서드나 멤버 변수에 접근할 수 있음

 

- Customer.java

// 디폴트 생성자 없애고 매개 변수가 있는 생성자 추가
public Customer(int customerID, String customerName) {
this.customerID = customerID;
this.customerName = customerName;

customerGrade = "SILVER";
bonusRatio = 0.01;
System.out.println("Customer(int, String) 생성자 호출");
}

 

- VIPCustomer.java

// super를 이용하여 상위 클래스의 생성자 명시적으로 호출
public VIPCustomer(int customerID, String customerName) {
super(customerID, customerName);

customerGrade = "VIP";
bonusRatio = 0.05;
salesRatio = 0.1;

System.out.println("VIPCustomer(int, String) 생성자 호출");
}

> super(customerID, customerName); 을 선언해준 이유는 Customer 생성자가 default 생성자가 아니기 때문.. 

만약 super를 명시적으로 호출하고 싶지 않다면 Customer.java에 default 생성자를 만들어주면 된다.

 

- CustomerTest.java

public class CustomerTest {

public static void main(String[] args) {

Customer customerLee = new Customer(10010, "이순신");
customerLee.bonusPoint = 1000;
System.out.println(customerLee.showCustomerInfo());

VIPCustomer customerKim = new VIPCustomer(10020, "김유신");
customerKim.bonusPoint = 10000;
System.out.println(customerKim.showCustomerInfo());
}
}

 

출력결과..

Customer(int, String) call...
이순신님의 등급은 SILVER이며, 보너스 포인트는 1000입니다.
Customer(int, String) call...
VIPCustomer(int, String) call...
김유신님의 등급은 VIP이며, 보너스 포인트는 10000입니다.

- VIPCustomer의 경우 생성자 호출시 먼저 상위 클래스의 Customer 생성자가 호출된다.

 

 

3. 상속에서 인스턴스 메모리 상태

항상 상위 클래스의 인스턴스가 먼저 생성되고, 하위 클래스의 인스턴스가 생성 된다.

이미지 출처 - https://gitlab.com/easyspubjava/javacoursework/-/blob/master/Chapter3/3-03/README.md

 

3-1. 형 변환(업 캐스팅)

  • 상위 클래스로 변수를 선언하고 하위 클래스의 생성자로 인스턴스를 생성한다.

ex) Customer customerLee = new VIPCustomer();

(이미 VIPCustomer는 Customer 생성자의 인스턴스를 가지고 있고 추가로 VIPCustomer의 인스턴스가 있기 때문에 가능)

* 위에 처럼 선언해도 VIPCustomer의 agentID나 salesRatio 인스턴스를 사용할 수는 없다. 오로지 Customer 형의 인스턴스만 사용할 수 있다. 

VIPCustomer의 인스턴스를 사용하려면 다시 다운 캐스팅을 하거나. 이후에 배울 오버라이딩(재정의)을 통해 가능하다.

 

  • 상위 클래스 타입의 변수에 하위 클래스 변수가 대입.

ex)

VIPCustomer vCustomer = new VIPCustomer();

addCustomer(vCustomer);

int addCustomer(Customer customer){}

 

  • 하위 클래스는 상위 클래스의 타입을 내포하고 있기 때문에 상위 클래스로 묵시적 형 변환이 가능하다.
  • 상속 관계에서 모든 하위 클래스는 상위 클래스로 형 변환(업 캐스팅)이 가능하다. (당연하게도 그 역은 성립하지 않음)

 

3-2. 형 변환과 메모리

  • Customer vs = new VIPCustomer();에서 vc가 가리키는 것은?
  • VIPCustomer() 생성자에 의해 VIPCustomer 클래스의 모든 멤버 변수에 대한 메모리는 생성되었지만 변수 타입이 Customer이기 때문에 실제로 접근 가능한 변수나 메서드는 Customer의 변수와 메서드이다.

이미지 출처 - https://gitlab.com/easyspubjava/javacoursework/-/blob/master/Chapter3/3-03/README.md
이미지 출처 - https://gitlab.com/easyspubjava/javacoursework/-/blob/master/Chapter3/3-03/README.md

 

728x90