[Java] 상속(inheritance)
본문 바로가기
Java

[Java] 상속(inheritance)

by IYK2h 2023. 5. 2.
728x90

상속(inheritance)

목차

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

자바 상속의 특징

"classes can be derived from other classes, thereby inheriting fields and methods from those classes."

  • Single inheritance (No diamond inheritance)
  • Object를 제외한 모든 클래스는 암묵적으로 Object의 서브클래스
  • 다단계 상속이 가능하고, 다중 상속을 지원하지 않는다.

https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

super 키워드

부모 클래스의 생성자나 메소드를 호출한다.

부모 생성자를 호출하는 경우를 특별히 constructor chanining이라고 부른다.

super()를 사용하면 슈퍼클래스의 no-argument 생성자가 호출됩니다. super(매개변수 목록)를 사용하면 일치하는 매개변수 목록이 있는 슈퍼클래스 생성자가 호출됩니다.

만약 자식 클래스의 생성자에서 super()를 명시적으로 사용하지 않으면, 컴파일러가 부모 클래스의 no-arg 생성자를 호출하도록 코드를 삽입한다. 그런데 만약 부모 클래스에 no-arg 생성자가 없다면, 컴파일 에러가 발생한다.

메소드 오버라이딩

class SuperClass {
    public void whoIAm() {
        System.out.println("I`m supper class.");
    }
}
​
class SubClass extends SuperClass {
​
    @Override
    public void whoIAm() {
        System.out.println("I`m sub class.");
    }
}
​
class Main {
    public static void main(String[] args) {
        SuperClass parent = new SuperClass();
        SubClass child = new SubClass();
​
        parent.whoIAm();
        child.whoIAm();
    }
}
​
//I`m supper class.
//I`m sub class.

@Override 어노테이션은 개발자에게 "오버 라이딩된 메서드" 라고 알려주는 역할과 부모 클래스에 없는 메서드에 어노테이션을 붙이면 컴파일 에러가 난다.

  Superclass Instance Method Superclass Static Method
Subclass Instance Method Overrides Generates a compile-time error
Subclass Static Method Generates a compile-time error Hides

오버라이딩 된 메소드의 Superclass의 메소드는 직접적으로 호출 불가.

하지만 Hides 상황에서는 Superclass의 메소드는 직접적으로 호출 가능.

다이나믹 메소드 디스패치 (Dynamic Method Dispatch)

"같은 클래스를 상속하고 있는 여러 클래스 중 어느 서브클래스를 사용할 것인가"를 런타임 시점까지 미룸으로서, 클래스 재사용성을 높이는 테크닉.

class Parent {
    void run() {
        System.out.println("Parent.run()");
    }
}
​
class Child1 extends Parent {
    @Override
    void run() {
        System.out.println("Child1.run()");
    }
}
​
class Child2 extends Parent {
    @Override
    void run() {
        System.out.println("Child2.run()");
    }
}
​
class Main {
    public void main(String[] args) {
        Parent child1 = new Child1();
        Parent child2 = new Child2();

        child1.run();
        child2.run();
    }
}
​
​
​
​
// result
​
Child1.run()
Child2.run()

추상 클래스

public abstract class GraphicObject {
   // declare fields
   // declare nonabstract methods
   abstract void draw();
}
  • 다음 설명 중 하나라도 해당되는 경우 추상 클래스를 사용하는 것이 좋습니다.
    • 밀접하게 관련된 여러 클래스 간에 코드를 공유하려고 합니다.
    • 추상 클래스를 확장하는 클래스에 공통 메서드 또는 필드가 많거나 공용이 아닌 액세스 한정자(예: 보호됨 및 개인)가 필요합니다.
    • 정적이 아니거나 최종이 아닌 필드를 선언하려고 합니다. 이렇게 하면 자신이 속한 개체의 상태에 액세스 하고 수정할 수 있는 메서드를 정의할 수 있습니다.
  • 다음 설명 중 하나라도 해당되는 경우 인터페이스 사용을 고려하세요.
    • 관련 없는 클래스가 인터페이스를 구현할 것으로 예상됩니다. 예를 들어 'Comparable''Cloneable' 인터페이스는 관련이 없는 많은 클래스에서 구현됩니다.
    • 특정 데이터 유형의 동작을 지정하려고 하지만 해당 동작을 구현하는 사용자는 상관하지 않습니다.
    • 형식의 다중 상속을 사용하려고 합니다.

https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

final 키워드

final은 재정의하는 것을 막는 키워드이다.

  • class
    • 클래스의 상속을 막는다.
  • variable
    • 변수의 재할당을 막는다.
  • method
    • 메서드의 오버라이딩을 막는다.

final의 오해

import java.util.ArrayList;
import java.util.List;
​
class Main {
​
    public static void main(String[] args) {
        final List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        System.out.println(list); // [1, 2, 3, 4, 5]

        list = new ArrayList<>(); // 오류! 재정의 금지!
    }
}

Object 클래스

java.lang.Object 클래스는 모든 클래스의 최상위 클래스이다.

메소드 설명
boolean equals(Object obj) 두 객체가 같은 지 비교한다.(같으면 true, 틀리면 false)
String toString() 객체의 문자열을 반환한다.
protected Object clone() 객체를 복사한다.
protected void finalize() 가비지 컬렉션 직전에 객체의 리소스를 정리할때 호출한다.
Class getClass() 객체의 클레스형을 반환한다.
int hashCode() 객체의 코드값을 반환한다.
void notify() wait된 스레드 실행을 재개할 때 호출한다.
void notifyAll() wait된 모든 스레드 실행을 재개할 때 호출한다.
void wait() 스레드를 일시적으로 중지할 때 호출한다.
void wait(long timeout),
void wait(long timeout, int nanos)
주어진 시간만큼 스레드를 일시적으로 중지할 때 호출한다.
728x90

'Java' 카테고리의 다른 글

[Java] 인터페이스(Interface)  (1) 2023.05.16
[Java] 패키지(Package)  (0) 2023.05.11
[Java] 클래스 Class  (0) 2023.04.28
[Java] JUnit5  (0) 2023.04.26
[Java] 제어문  (0) 2023.04.24

댓글