ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java - 상속과 다형성(super)2
    개발언어/JAVA 2023. 10. 17. 15:29

    상속에서 상위클래스와 하위클래스 그리고 super 예약어

    상속에서 클래스 생성과 형 변환

    하위 클래스의 인스턴스가 생성될 때는 상위 클래스의 인스턴스 생성자가 먼저 호출된다. 상속 관계에서 인스턴스의 생성 과정을 살펴보면 하위 틀래스가 상위 클래스의  변수과 메서드를 사용할 수 있는 이유와 하위 클래스가 상위클래스의 자료형으로 형 변환 할 수 있는 이유를 이해할 수 있다.

     

     

    상위 클래스 생성자가 호출될 때 상위 클래스의 멤버 변수의 메모리가 힙 메모리에 생성되는 것이다. 하위 클래스 VIPCustomer가 생성될 때 메모리 구조를 그려보면 위와 같다. 위 그림과 같이 상위 클래스  변수가 메모리에 먼저 생성되기 때문에 하위 클래스에서 이 값들을 모두 사용할 수 있다. 상위 클래스의 변수를 private으로 선언한 경우 하위 클래스에서 해당 변수를 사용할 수 없었던 것은 상위 클래스의 변수가 생성되지 않았기 때문일까? 그건 아니다. private 변수가 생성은 되지만 단지 하위 클래스에서 접근할 수 없었을 뿐이다.

     

    부모를 부르는 예약어,super

    super 예약어는 하위 클래스에서 상위클래스로 접근할 때 사용한다. 하위 클래스는 상위클래스의 주소, 즉 참조 값을 알고 있다. 이 참조값을 가지고 있는 예약어가 바로 super이다. this가 자기 자신의 참조 값을 가지고 있는 것과 같다고 생각하면 된다. 또한 super는 상위 클래스의 생성자를 호출하는 데도 사용한다.

     

    상위 클래스 생성자 호출하기

       ...
    
    public VIPCustomer(){
        // 컴파일러가 자동으로 추가하는 코드.
        // 상위 클래스의 생성자 Customer()가 호출된다.
        super();
        customerGrade = "VIP";
        bonusRatio = 0.05;
        saleRatio = 0.1;
    }

    실제로 위 코드와 같이 super를 명시 하지 않아도 자바 프로그램시 VIPCustomer 클래스 생성자를 통해서 VIPCustomer 인스턴스를 만들 경우 생성자에서 super()를 자동으로 호출한다. 위와 같이 하위 클래스에서 super()를 명시하여 호출하면 상위 클래스의 디폴트 생성자를 집어서 호출하겠다는 의미이다. 

     

       ...
       
       pubic Customer(){
       
       }
       
       ...

    또 한 VIPCustmer 클래스 인스턴스 생성시 묵시적으로 super()를 호출하려면 Customer 클래스의 default 생성자를 명시해주어야 한다. 그렇지 않고 Customer 클래스의 default 생성자를  명시적을로 정의 해주지 않으면 VIPCustmer 클래스 인스턴스 생성시 묵시적으로 super()를 호출하는 과정에서 문제가 발생해 오류 메시지를 반환한다.

     

    super()예약어로 매개변수가 있는 생성자 호출하기

    이런 경우를 생각해 보자. Customer 클래스를 생성할 때 고객 ID와 이름을 반드시 지정해야 한다고 가정하자 이런 경우에 set()메서드로 인스턴스 생성후 멤버 변수의 값을 지정하는 것이 아니라 새로운 생성자를 만들어서 매개변수로 값을 전달 받아야한다. 즉 디폴트 생성자가 아닌 매개변수가 있는 생성자를 하위 클래스에서 직접 구현해야한다.

     

       ...
       
       public Customer(int customerID, String customerName){
          this.customerID = customerID;
          this.customerName = customerName;
          customerGrade = "SILVER";
          bonusRatio=0.01;
       }
       
       ...

     

       ...
       
       public VIPCustomer(int customerID, String custoemrName, int agentID){
        super(customerID, customerName);
        customerGrade = "VIP";
        bonusRatio = 0.05;
        saleRatio = 0.1;
        this.agentID = agentID;
       }
       
       ...

    위와 같이 Customer 클래스 생성자와 VIPCustomer 클래스 생성자를 각가 클래스 정의시 명시해주면, super()를 통해 Customer(int customerID, String customerName)상위 클래스 생성자를 호출하고 코드 순서대로 멤버 변수가 초기화 된다. 즉 상위 클래스의 호출이 끝나고 VIPCustomer하위 클래스 생성자의 내부 코드 수행이 마무리된다.

     

    상위 클래스의 멤버 변수나 메서들 참조하는 super

    상위 클래스에 선언한 멤버 변수나 메서드를 하위 클래스에서 참조할 때도 super를 사용한다. this를 사용하여 자신의 멤버에 접근했던과 비슷하다. 예를 들어 VIPCustomer 클래스의 showVIPInfo()메서드에서  상위클래스(Customer 클래스)의 showCustomerInfo()메서드를  참조해 담당 상담원 아이디를 추가로 출력하려고 하때 다음과 같이 구현할 수 있다.

       ...
       
    public String showVIPInfo(){
       return super.showCustomerInfo()+ "담당 상담원 아이디는 " + agentID + "입니다.";
    }
    
    	...

    super 예약어는 상위 클래스의 참조 값을 가지고 있으므로 위 코드처럼 사용하면 고객 정보를 출력하는 showCustomerInfo()메서드를 새로 구현하지 않고 상위 클래스의 구현 내용을 활용할 수 있다.

     

    '개발언어 > JAVA' 카테고리의 다른 글

    Java - 상속 다형성(다형성 활용하기)6-1  (1) 2023.11.03
    Java - 상속과 다형성(다형성)5  (1) 2023.11.01
    Java - 상속과 다형성(상속)1  (1) 2023.10.17
    Java - Object4  (1) 2023.10.17
    Java - Object3  (1) 2023.10.16

    댓글

Designed by Tistory.