[Java] Inheritance (vs. composition)

janeljs·2021년 1월 14일
3

Java

목록 보기
3/17
post-thumbnail

상속

기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것

사용 방법

class Parent {}
class Child extends Parent { ... }
  • Child class는 Parent class의 모든 멤버를 상속받기 때문에 상속을 거듭할수록 멤버 개수가 늘어난다.
    ※ 단 생성자와 초기화 블럭은 상속되지 않는다.
  • 상속을 구현하기 위해서는 자식 클래스가 조상 클래스를 확장한다는 의미로 extends 키워드를 사용한다.

상속의 장점

  1. 적은 양의 코드로 새로운 클래스를 작성할 수 있다.
  2. 공통적으로 코드를 관리하기 때문에 코드의 추가 및 변경이 용이하다.

단일 상속

  • C++은 multiple inheritance가 가능하지만, java는 single inheritance만 가능하다.
  • 다중 상속을 구현하면 여러 클래스로부터 상속받기 때문에 복합적인 기능을 가진 클래스를 쉽게 작성할 수 있지만, 선언부(이름, 매개변수)가 같고 내용은 다른 인스턴스 메서드가 어떤 클래스로부터 왔는지 추적할 수 없다. 따라서 java는 클래스 간의 관계를 명확하게 해주는 단일 상속(single inheritance)만 지원한다.

super & super()

super

자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수
※ 모든 인스턴스 메서드에는 this와 super가 지역 변수로 존재하며, this와 super에는 각각이 속한 인스턴스 주소가 자동으로 저장된다.

class Parent {
    String x = "parent";
}

class Child extends Parent {
    String x = "child";

    void method() {
        System.out.println("x = " + x);
        System.out.println("this.x = " + this.x);
        System.out.println("super.x = " + super.x);
    }
}

// Result
// x = child
// this.x = child
// super.x = parent

super()

조상의 멤버는 조상의 생성자를 통해 초기화하는 것이 바람직한데, 이 때 조상의 생성자를 호출하는데 사용하는 것이 super()이다.
※ this(): 같은 클래스의 다른 생성자를 호출하는데 사용

public class Point {
    int x, y;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class Point3D extends Point {
    int z;

    Point3D(int x, int y, int z) {
        super(x, y);
        this.z = z;
    }
}

Inheritance vs. composition

코드 재사용에는 두 가지 방법이 있는데 하나는 inheritance이고 하나는 composition이다.

class Circle {
	int x;
    int y;
    int r;
}

class Point {
    int x;
    int y;
}

Inheritance

예를 들어 위와 같이 Point 클래스가 있고 Point 클래스의 멤버 변수를 모두 포함하는 Circle 클래스가 있을 때 Point 클래스를 상속한다면 아래와 같이 표현할 수 있다.

class Circle extends Point {
    int r;
}

Composition

Composition은 클래스 간에 포함(composite) 관계를 맺어주는 것,
즉, 한 클래스의 멤버변수로 다른 클래스 타입의 참조 변수를 선언하는 것을 의미한다.

class Circle {
    Point c = new Point();
    int r;
}

위와 같이 Point 클래스를 Circle 클래스의 멤버 변수로 선언함으로써 포함 관계를 맺을 수 있다.

그렇다면 상속 관계를 맺을지, 포함 관계를 맺을지는 어떻게 결정하면 좋을까?

Circle is a Point.
Circle has a Point

위의 예제에서는 원이 점이라기 보다는 원이 점을 가지고 있는 것이기 때문에 포함 관계를 맺어주는 것이 더 적합하다. 다시 말해 Inheritance는 object 사이에 is-a relationship을 갖고 있을 때 사용되며, compostion은 has-a relationship을 갖고 있을 때 사용된다.


Source

profile
알고리즘 풀이는 👉 janeljs.github.io 👈에 올려요💓

0개의 댓글