경주장

6주차 과제: 상속 #6 (~02.29) - 자바 상속의 특징 본문

JAVA/whiteship_live-study

6주차 과제: 상속 #6 (~02.29) - 자바 상속의 특징

달리는치타 2022. 2. 22. 15:37

 목표

자바의 상속에 대해 학습하세요.

✔️ 학습할 것 (필수)

  • 자바 상속의 특징
  • 메소드 오버라이딩
  • super 키워드
  • 다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
  • 추상 클래스
  • final 키워드
  • Object 클래스

다른 학습자분의 포스팅을 보니 Oracle 공식문서를 참고하는 분이 계셔서 저도 한번 따라해 보겠습니다 ㅎ.ㅎ


자바 상속의 특징

Def - subclass, superclass
A class that is derived from another class is called a subclass
The class from which the subclass is derived is called a superclass

 

특징 1  - Single Inheritance(단일 상속)

Excepting Object, which has no superclass, every class has one and only one direct superclass. In the absence of any other explicit superclass, every class is implicitly a subclass ofObject

 

상속의 아이디어는 간단하지만 강력합니다. 새로운 클래스를 만들고 싶고 기능을 일부 포함하는 클래스가 이미 있다면 상속을 통해 기존 클래스의 모든 members를 재사용 할 수 있습니다.

 

subclass는 superclass의 모든( all) members (fields, methods and nested classes)를 상속 받습니다. 이때 생성자는 memeber가 아닙니다. 따라서 생성자는 상속의 대상이 아닙니다. 하지만 superclass의 생성자는 subclass에서 호출 될 수 있습니다.

자바 플랫폼의 모든 클래스는 Object의 후손(Descendants)입니다.

 

all members라고 표현 하였지만 접근 제어자에 따라 접근이 불가능한 필드, 메소드의 경우 상속의 대상이 아닙니다.

즉 public, protected의 경우 무조건 상속의 대상이 되자만 private 의경우 상속의 대상이 되지 않습니다. package-private (default) 접근제어자를 지닌 필드, 메소드의 경우 상속받은 subclass가 superclass와 같은 패키지에 있다면 상속의 대상이 됩니다.

 

특징 2  - dose not allow multiple inheritance (다중 상속을 지원하지 않음)

특징 1의 문장을 자세히 보면 'One and only one' 이라는 표현이 있습니다. 즉, 자바의 상속은 다중상속을 지원하지 않습니다.

 

Oracle document는 다중상속을 지원하지 않는 이유를 아래와 같이 표현합니다.

One reason why the Java programming language does not permit you to extend more than one class is to avoid the issues of multiple inheritance of state

자바 언어가 다중 상속을 지원하지 않는 이유 중 하나는 "다중 상속 상태 문제"를 예방하기 위해서이다.

"다중 상속 상태 문제"란 다중 상속이 발생했을때 두 클래스의 메서드나 생성자가 같은 필드, 메서드 이름을 가지면 어떻게 대응하는가에 관한 이슈이다.

 

상속과 달리 인터페이스의 다중 구현은 가능합니다. 심지어 같은 시그니처를 가진 추상 메서드를 포함한 두 인터페이스의 경우도 다중 구현을 지원합니다. 아래와 같은 코드에서 출력으로 hello가 두줄찍힙니다.

 

public class Main {

    public static void main(String[] args) {
        A a = new C();
        a.hello();

        B b = new C();
        b.hello();
    }
}

interface A{
    void hello();
}

interface B{
    void hello();
}

class C implements A, B{
    @Override
    public void hello() {
        System.out.println("hello");
    }
}

 

개발자는 위와같은 상황에서 모호함을 없에기 위해 인터페이스에 default 메서드를 구현할 수 있습니다.