코드 그라데이션

Day23. super 본문

Java/Mega

Day23. super

완벽한 장면 2023. 4. 17. 19:34

super

- 상속에서 부모의 것을 의미함.

- 부모 클래스의 생성자를 자식 클래스 생성자에서 활용할 때 필요함. super()

super는 상속받은 부모 클래스에 대한 레퍼런스 변수

=> 부모 클래스 멤버에 접근할 때 사용하는 키워드

 

/ 자식 클래스의 모든 생성자는 부모 클래스 생성자를 포함하고 있어야 하는데,

그렇지 않은 경우 자바 컴파일러가 사실 자동으로 부모 클래스의 기본 생성자를 호출해준다.

(만약, 부모 클래스에 기본 생성자가 없다면, 에러 <- 매개변수 존재하는 생성자만 있는 경우)

 

 

예시

super > 부모 클래스

super. > 부모생성자

부모클래스() // 부모의 생성자

super.abc() // 부모의 메소드

super.a // 부모의 멤버 변수

 

또 예시

class A {
    A(int a) {

    }
}

class B extends A {
    B() {
        super(5);
    }
}

public class Main {
    public static void main(String[] args) {
        B b = new B();
    }
}

해설

A 클래스는 int 타입의 파라미터를 받는 생성자만 정의되어 있습니다. 
B 클래스는 A 클래스를 상속하며, 파라미터를 받지 않는 생성자를 정의하고, 
super 키워드를 사용하여 A 클래스의 int 타입 파라미터를 받는 생성자를 호출합니다. 
main() 메소드에서는 B 클래스의 객체를 생성합니다.

이제 실행 흐름을 설명하겠습니다.

main() 메소드에서 B 클래스의 객체를 생성합니다.

B 클래스의 생성자가 호출됩니다.

B 클래스의 생성자에서 super(5); 구문이 실행됩니다.

super(5); 구문은 A 클래스의 int 타입 파라미터를 받는 생성자를 호출합니다.

A 클래스의 생성자는 파라미터 5를 받고 실행됩니다.

A 클래스의 생성자 실행이 완료되면 B 클래스의 생성자도 실행이 완료됩니다.

main() 메소드에서 B 클래스의 객체 생성이 완료되고 프로그램이 종료됩니다.

따라서, 위 코드의 실행 결과는 아무것도 출력되지 않습니다.

 

또 예시

 

Class A{

    A(int a){

   }

   A(String str){

   }

}

Class B extends A{

    B(int a){

       super(a);

    }

    B(){

       super(5);

    }

}

해설

A 클래스에는 int 타입의 a 파라미터를 받는 생성자와 
String 타입의 str 파라미터를 받는 생성자가 있습니다.

B 클래스는 A 클래스를 상속하므로, A 클래스의 모든 메소드와 인스턴스 변수를 상속합니다. 
B 클래스에는 두 개의 생성자가 있습니다.

B 클래스의 첫 번째 생성자는 int 타입의 a 파라미터를 받고, 
super 키워드를 사용하여 A 클래스의 int 타입 파라미터를 받는 생성자를 호출합니다.

B 클래스의 두 번째 생성자는 파라미터를 받지 않고, 
super 키워드를 사용하여 A 클래스의 int 타입 파라미터를 받는 생성자를 호출합니다. 
이 때, 파라미터 값으로 5를 전달합니다.


요약하면, 
B 클래스는 A 클래스의 하위 클래스이며, 
int 타입의 파라미터를 받는 A 클래스의 생성자를 호출하는 두 개의 생성자가 있습니다. 
두 번째 생성자는 파라미터를 받지 않고, 5를 전달합니다.

 

이 경우 A생성자 안에 있는 a에 5가 꽂힘.

 

 

예시 1

class A{
  int k; // 여기에 5가 들어감. super로 불렀으니까.

  A(int a){
    this.k = a;
  }

  void print() {
    System.out.println("A");
  }
}




class B extends A{
  int k; // 그러면 여기에 5가 들어간다.
  B(){
    super(5); // 이건 int a를 받는 부모 생성자가 있기 때문.
  }

  void print() {
    System.out.println(super.k); // 부모 클래스 A의 k 필드에 접근하기 위해 super.k 사용
  }
}


public class TestSuper {

  public static void main(String[] args) {

    B b = new B();
    b.print(); // A출력 -> 5 출력 : 메서드 오버라이딩 한 게 되므로.
    // 만약에 b에 print 메서드가 없었다면, A가 출력 되었을 것임.
    // 지금 내가 의도적으로 print 메서드를 설정해놨음. 차이를 확인하기 위해서.


  }

}

 

예시 2.

class Z { // 조부모 클래스를 추가함.

  String str;

  Z(String str) {
    this.str = str;
  }
}

class A extends Z {

  int k;

  A(int a) { // 이 상태면 에러, 조부모(부모) 요소 찾아와야.
    super("hello");
    this.k = a;
  }

  void print() {
    System.out.println("A");
  }
}

class B extends A {

  String str; // 여기에 hi가 들어가는 것.
  int k; // 그러면 여기에 5가 들어간다.

  B() {
    super(5); // 이건 int a를 받는 부모 생성자가 있기 때문.
  }

  void changeString() {
    super.k = 5; // 부모꺼
    this.k = 10; // 내꺼
  }


  public class TestSuper {

    public static void main(String[] args) {

      B b = new B();
      b.print();
      b.str = "hi";

    }
  }

}

 

728x90
Comments