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개를 일일이 다 수정해줘야한다. 이렇게 상속은 강한결합관계로 인해서 유연하게 대처하기 어렵다는 단점이 있다.
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을 선호하라"는 원칙이 있으며, 이는 유연성과 유지보수성을 높이는 것에 도움을 준다.
https://tecoble.techcourse.co.kr/post/2020-05-18-inheritance-vs-composition/