[JAVA] Inheritance(상속)과 Composition(조합)

JHJeong·2024년 4월 2일
0

Inheritance(상속)

  • 한 클래스가 다른 클래스의 속성과 메소드를 물려받는 매커니즘
  • 이를 통해서 기존 소스코드를 재사용하고 확장할 수 있으며, 계층구조를 통해 클래스 간의 관계를 명확히 할 수 있음
    장점
  • 코드 재사용 : 공통적인 로직을 부모 클래스에 정의하고, 여러 자식 클래스가 이를 상속받을 수 있음
  • 계층 구조 : 클래스 간의 계층적 관계를 구축하여, 객체 모델을 더 명확하게 표현할 수 있음
    단점
  • 강한 결합 관계 : 자식 클래스가 부모 클래스에 강하게 결합되어, 부모 클래스의 변경이 자식 클래스에 영향을 미칠 수 있음
  • 재사용성의 한계 : 특정 기능이 필요한 모든 클래스에서 상속을 사용하면, 불필요한 메소드를 상속받거나, 상속의 깊이가 깊어져 복잡성이 증가할 수 있음
  • 캡슐화를 깨짐 : 상위 클래스의 구현이 하위 클래스에서 노출되는 상속은 캡슐화를 깨뜨리되고, 이는 하위 클래스와 상위 클래스 간의 강한 결합 관계 때문에 유연하게 대처하기 어려워짐
    ( 캡슐화 : 만일의 상황(타인의 외부에서 조작)에 대비해 외부에서 특정 속성이나 메소드를 사용할 수 없도록 숨겨놓는 것. )
class Vehicle {
    public void move() {
        System.out.println("Vehicle is moving");
    }
}

class Car extends Vehicle {
    @Override
    public void move() {
        super.move();
        System.out.println("Car is moving fast");
    }
}

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.move();
    }
}

실행 결과
Vehicle is moving
Car is moving fast

위와 같은 Vehicle 클래스의 요구사항이 바뀌어서 stop() 메소드나 인스턴스 변수와 생성자들이 추가된다고 하면, 하위 클래스인 Car 클래스도 강한결합관계이기 때문에 수정해줘야 사용할 수 있게된다. 만약 Vehicle 클래스를 상속받는 하위 클래스가 100개라고 하면 100개를 일일이 다 수정해줘야한다. 이렇게 상속은 강한결합관계로 인해서 유연하게 대처하기 어렵다는 단점이 있다.

Composition(조합)

  • 객체가 다른 객체를 포함하는 방식으로, 한 객체가 다른 객체의 인스턴스를 "가지고 있음"을 나타냄
    ( private 필드로 기존 클래스의 인스턴스를 참조함 )
  • 이 방식은 더 유연한 코드 재사용성과 느슨한 결합을 가능하게 됨
    장점
  • 유연성 : 구성 요소를 쉽게 교체하거나 수정할 수 있어, 시스템의 동작을 유연하게 변경할 수 있음
  • 느슨한 결합 : 객체 간의 종속성이 줄어들어, 시스템의 각 부분을 독립적으로 개발하고 테스트할 수 있음
    단점
  • 설계 복잡성 : 올바른 설계를 위해서는 추가적인 설계 고려사항이 필요하며, 때로는 구성 관계를 설정하는데 있어서 복잡성이 증가할 수 있음
  • 간접적인 메시지 패스 : 객체 간의 관계가 더 복잡해질 수 있으며, 때로는 구성 요소를 통해 메시지를 전달하는 것이 직접적이지 않을 수 있음

interface Movable {
    void move();
}

class Vehicle implements Movable {
    public void move() {
        System.out.println("Vehicle is moving");
    }
}

class Car {
    private Movable movable;
    
    public Car(Movable movable) {
        this.movable = movable;
    }
    
    public void move() {
        movable.move();
        System.out.println("Car is moving fast");
    }
}

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car(new Vehicle());
        myCar.move();
    }
}

실행 결과
Vehicle is moving
Car is moving fast

상속은 계층적 관계를 명확히 하고 코드를 재사용하기 쉽게 하지만, 클래스 간의 강한 결합과 유연성의 제한이라는 단점이 있다. Composition은 시스템의 유연성과 느슨한 결합을 제공하지만, 설계와 구현이 더 복잡해질 수 있다.
일반적으로 "상속보다는 Composition을 선호하라"는 원칙이 있으며, 이는 유연성과 유지보수성을 높이는 것에 도움을 준다.

<참고>

  • 강한결합(Strong Coupling) 관계 : 시스템의 두 구성 요소가 서로 긴밀하게 연결되어 있어, 한 부분의 변경이 다른 부분에 큰 영향을 미치는 관계, 한 컴포넌트가 다른 컴포넌트의 내부 구현에 대해 많이 알고 있으며, 이로 인해 두 컴포넌트는 서로에게 매우 의존적임
  • 약한결합(Loose Coupling) 관계 : 시스템의 구성 요소들이 서로 독립적이며, 한 컴포넌트의 변경이 다른 컴포넌트에 미치는 영향이 최소화된 관계, 컴포넌트들은 필요한 최소한의 정보만을 서로 공유하며, 인터페이스나 추상 클래스를 통해 서로 소통함

출처

https://tecoble.techcourse.co.kr/post/2020-05-18-inheritance-vs-composition/

profile
이것저것하고 싶은 개발자

0개의 댓글