[Java 상속] 상속vs조합 - 다중상속 유무는?

Java에서 클래스 간 관계를 설계할 때 사용되는 상속(Inheritance)과 조합(Composition)의 특징과 활용 방법을 설명하는 문서입니다. 다중상속은 자바에서 왜 지원 안 할까요?



상속의 기본 특징

별도의 extends 선언이 없어도 모든 Java 클래스는 암시적으로 Object 클래스를 상속

super() 호출은 자식 클래스 생성자의 첫 줄에서만 가능

class Parent {
    Parent() { }
}

class Child extends Parent {
    Child() {
        super(); // 반드시 생성자 첫 줄에 위치
    }
}


아래 그림은 SpiderMan이 Person을 상속받고, Person이 암묵적으로 Object를 상속받는 구조

상속클래스구조



상속 vs 조합

클래스 간의 관계를 명시적으로 표현할 수 있는 경우라면 “상속”을 사용하고 그렇지 않은 경우에는 “조합”을 사용하자.


상속(Inheritance)

  • is-a 관계를 표현
  • 캡슐화가 깨질 수 있는 단점 존재
class Human extends Mammal {  // 사람은 포유류이다
    // ...
}


조합(Composition)

  • has-a 관계를 표현
  • 기존 클래스가 새로운 클래스의 구성 요소로 쓰인다. 즉, private 필드로 다른 클래스를 포함
class Car {
    private Battery battery;  // 자동차는 배터리를 가진다
    // ...
}

조합(포함)관계 좀 더 자세히..

Image

코드로 보는 is a, has a 사용한 재활용 방법

public class Person {
    String name;
    
    void eat(){}
    void jump(){}
}

public class Spider {
    void fireWeb() {System.out.println("거미줄 발사");}
}

public class SpiderMan extends Person {  // SpiderMan is a Person:상속
    Spider spider = new Spider(); // SpiderMan has a Spider:합성
    boolean isSpider;
    
    void fireWeb(){
        if(this.isSpider) { this.spider.fireWeb(); }
        else { System.out.println("사람은 거미줄을   없습니다!); }
    }
}



Java가 다중상속 제한하는 이유? 🔍

Java는 단일상속 원칙: 다이아몬드 문제 방지
동일한 메소드를 가진 두 부모 클래스 상속 시 발생하는 충돌 예방

단일 상속 극복 방안: 인터페이스와 포함 관계(has a)로 단점 극복

interface Flyable {
    void fly();
}

interface Flyable2 {
    void fly2();
}

class Bird {
    void eat() { }
}

public class Spider {
    void fireWeb() {System.out.println("거미줄 발사");}
}

class Eagle extends Bird implements Flyable,Flyable2 { //인터페이스 여러개 상속 가능
    Spider spider = new Spider(); //has a
    @Override
    public void fly() { }
}

클래스 설계 시 상속과 조합의 특징을 고려하여 적절한 방식을 선택해야 합니다.

댓글남기기