상속

2024. 3. 13. 17:42

 

상속과 메모리 구조

new ElectricCar()를 호출하면 ElectricCar 뿐만 아니라 상속 관계에 있는 Car까지 함께 포함하여 인스턴스를 생성한다.

참조값은 x001로 하나이지만 실제로 그 안에는 두 개의 클래스 정보가 공존하는 것.

상속이라고 단순하게 부모의 필드와 메서드만 물려 받는게 아니다. 상속 관계에서는 부모 클래스도 함께 포함해서 생성된다. 외부에서 볼 때는 하나의 인스턴스를 생성하는 것 같지만 내부에서는 부모와 자식이 모두 생성되고 공간도 구분된다.

====================================================================================

 

Car와 ElectricCar 둘 중에 호출하는 변수의 타입(클래스)를 기준으로 선택한다.

====================================================================================

 

====================================================================================

 

실행할 메서드를 찾았음으로 부모 타입을 찾지 않는다.

====================================================================================

 

오버로딩(Overloading) vs 오버라이딩(Overriding)

  • Overloading : 메서드 이름이 같고 파라미터가 다른 메서드를 여러 개 정의하는 것. 번역하면 과적인데, 과하게 물건을 담았다는 뜻이다. 같은 이름의 메서드를 여러개 정의한 것.
  • Overriding : 하위 클래스에서 상위 클래스의 메서드를 재정의하는 과정. 상속 관계에서 사용한다. 부모의 기능을 자식이 다시 정의하는 것. 무언가를 넘어서 타는 것을 말한다. 재정의라는 말.
    • 조건
      1. 메서드 이름이 같아야 한다.
      2. 파라미터 타입, 순서, 개수가 같아야 한다.
      3. 반환 타입이 같아야 한다. 단 반환 타입이 하위 클래스 타입일 수 있다.
      4. 접근 제어자 : 오버라이딩 메서드의 접근 제어자는 상위 클래스의 메서드보다 더 제한적이어서는 안된다. 예를 들어 상위 클래스의 메서드가 protected이면 하위 클래스에서 public or protected는 가능하지만 private or default로 오버라이딩 할 수 없다.
      5. 예외 : 오버라이딩 메서드는 상위 클래스의 메서드보다 더 많은 체크 예외를 throws로 선언할 수 없다. 하지만 더 적거나 같은 수의 예외, 또는 하위 타입의 예외는 선언할 수 있다.
      6. static, final, private 키워드가 붙은 메서드는 오버라이딩 될 수 없다.
        1. static은 클래스 레벨에서 작동하므로 인스턴스 레벨에서 사용하는 오버라이딩이 의미가 없다. 쉽게 이야기해서 그냥 클래스 이름을 통해 필요한 곳에 직접 접근하면 된다.
        2. final 메서드는 재정의를 금지한다.
        3. private 메서드는 해당 클래스에서만 접근 가능하기 때문에 하위 클래스에서 보이지 않는다.
      7. 생성자는 오버라이딩 할 수 없다.

 

 

 

super - 부모 참조

부모와 자식의 필드명이 같거나 메서드가 오버라이딩 되어 있으면, 자식에서 부모의 필드나 메서드를 호출할 수 없다. super 키워드를 사용하면 부모를 참조할 수 있다. super는 이름 그대로 부모 클래스에 대한 참조를 나타낸다.

 

super - 생성자

 

  • 상속 관계의 인스턴스를 생성하면 메모리 내부에는 자식과 부모 클래스가 각각 다 만들어진다. 따라서 각각의 생성자도 모두 호출되어야 한다.
  • 상속 관계를 사용하면 자식 클래스의 생성자에서 부모 클래스의 생성자를 반드시 호출해야 한다.(규칙) = super(...)
  • 상속을 받으면 생성자의 첫줄에 super(...)를 사용해서 부모 클래스의 생성자를 호출해야 한다.
    • 예외로 생성자 첫줄에 this(...)를 사용할 수는 있다. 하지만 super(...)는 자식의 생성자 안에서 언젠가는 반드시 호출해야 한다.
  • 부모 클래스의 생성자가 기본 생성자인 경우에는 super()를 생략할 수 있다.
    • 상속 관계에서 첫 줄에 super(...)를 생략하면 자바는 부모의 기본 생성자를 호출하는 super()를 자동으로 만들어준다.
    • 기본 생성자를 많이 사용하기 때문에 편의상 이런 기능을 제공한다.
  • 따라서 초기화는 최상위 부모부터 실행되어서 하나씩 아래로 내려오는 것이다. 왜냐하면 자식 생성자의 첫 줄에서 부모의 생성자를 호출해야 하기 때문이다. = 부모가 먼저 세팅이 되어야 자식이 기능을 물려받을 수 있음 = super()를 해줘야 하는 이유

정리 

 - 상속 관계의 생성자 호출은 결과적으로 부모에서 자식 순서로 실행된다. 따라서 부모의 데이터를 먼저 초기화하고 그 다음에 자식의 데이터를 초기화한다.

 - 상속 관계에서 자식 클래스의 생성자 첫 줄에 반드시 super(...)를 호출해야 한다. 단 기본 생성자인 경우에는 생략 가능

 

 

 

 

QA. super()를 언제 생략할 수 있는지? 생성자 측면에서

'Java' 카테고리의 다른 글

직렬화 역직렬화  (0) 2024.04.10
Garbage Collection  (1) 2024.04.10
OOP(Object Oriented Programming)  (0) 2024.04.05
쓰레드(Thread)  (0) 2024.04.05
예외 처리 (Java)  (0) 2024.04.05

BELATED ARTICLES

more