[JAVA]상속 (Inheritance)

객체 지향 프로그래밍에서 중요한 개념으로 추상화, 상속, 다형성, 캡슐화가 있다.

그 중, 상속에 대해 정리해보자.

상속

상위 클래스의 자산을 하위 클래스에서 사용할 수 있도록 하는 메커니즘이다.

이를 통해 코드의 재사용성을 높이고, 계층 구조를 통해 체계적으로 프로그램을 설계할 수 있다.

기본 개념

상속을 통해 상위 클래스의 속성과 메서드를 하위 클래스에서 사용할 수 있다.

사용법

자바에서는 extends 키워드를 사용하여 클래스가 다른 클래스를 상속받도록 한다.

class Parent {
    // 상위 클래스의 속성과 메서드
}

class Child extends Parent {
    // 상위 클래스의 자산을 상속받음
}

별도의 extends 선언이 없는 클래스들은 extends Object 가 생략되어있다.

자바에서 모든 클래스는 자동으로 Object 클래스를 상속받는다.

명시적으로 extends를 사용하지 않은 클래스는 extends Object가 생략된 것이다.

class MyClass {
    // Object 클래스의 메서드를 사용할 수 있음
}

is-a 관계와 has-a 관계

상속은 주로 is-a 관계를 나타낼 때 사용된다.

ex) SpiderMan 클래스가 Person 클래스를 상속받는 경우 SpiderMan is-a Person이 된다.

has-a 관계는 클래스가 다른 클래스를 포함할 때 사용된다.

ex) SpiderMan이 SpiderFeat를 포함할 때 SpiderMan has-a SpiderFeat이 됩니다. (this. SpiderFeat = new SpiderFeat(); 사용)

메서드 오버라이딩 (Method Overriding)

메서드 오버라이딩은 상위 클래스에 정의된 메서드를 하위 클래스에서 재정의하여, 하위 클래스에 적합하게 수정하는 것이다.

  • 반드시 상위 클래스의 메소드와 형식 일치해야 한다. (매개변수의 개수, 타입, 순서 일치)
  • 단 접근제어자는 override시 상위 보다 넓은 의미면 가능하다
  • 상위 클래스의 예외보다 더 큰 위의 예외를 던질 수 없다.
class Parent {
    void display() {
        System.out.println("Parent Display");
    }
}

class Child extends Parent {
    @Override
    void display() {
        System.out.println("Child Display");
    }
}

이 경우, Child 클래스의 display 메서드는 Parent 클래스의 display 메서드를 오버라이딩한다.

super 키워드

super 키워드는 상위 클래스의 메서드나 생성자에 접근할 때 사용된다.

이를 통해 하위 클래스에서 상위 클래스의 메서드를 호출하거나, 상위 클래스의 생성자를 명시적으로 호출할 수 있다.

명시적으로 super()을 호출하지 않는 경우, 컴파일러가 super() 삽입한다.

class Parent {
    void display() {
        System.out.println("Parent Display");
    }
}

class Child extends Parent {
    @Override
    void display() {
        super.display(); // 상위 클래스의 display 메서드 호출
        System.out.println("Child Display");
    }
}

또한 생성자에서 super를 사용하여 상위 클래스의 생성자를 호출할 수 있다.

class Parent {
    Parent() {
        System.out.println("Parent Constructor");
    }
}

class Child extends Parent {
    Child() {
        super(); // 상위 클래스의 생성자 호출, 자식 클래스 생성자의 맨 첫줄에만 호출가능, this()와 중복 작성 불가능
        System.out.println("Child Constructor");
    }
}

cf) super vs this this() : 자신의 생성자 호출 상위 클래스의 생성자 호출