[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; // 자동차는 배터리를 가진다
// ...
}
조합(포함)관계 좀 더 자세히..
코드로 보는 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() { }
}
클래스 설계 시 상속과 조합의 특징을 고려하여 적절한 방식을 선택해야 합니다.
댓글남기기