자바의 단점은 다중상속이 안된다는 점이다. 또한 상속은 다형성과 재사용이 함께 있어야 한다.
다중상속을 해야하는 경우나, 다형성과 재사용이 동시에 충족되지 않으면 컴포지션을 사용해야한다.
컴포지션의 예를 햄버거 가게로 예를 들어보자.
가장 기본적인 버거를 보자.
@Data //Getter, Setter 추가
public class Burger {
private int price;
private String desc;
public Burger() {
this(1500,"기본 버거");
}
// 최종목적지
public Burger(int price, String desc) {
this.price = price;
this.desc = desc;
System.out.println(desc+"가 만들어졌습니다.");
}
}
생각해보자. 큰 버거도 햄버거고, 새우버거도 햄버거다. 따라서 햄버거를 부모로 상속하여 다른 버거들을 만드는 것도 가능할 것이다.
- 새우버거
public class ShrimpBurger extends Burger{
public ShrimpBurger() {
super(3500,"쉬림프 버거");
}
public ShrimpBurger(int price, String desc) {
super(price, desc);
}
}
- 빅버거
public class Bigburger extends Burger{
public Bigburger() {
super(4000,"빅버거");
}
public Bigburger(int price, String desc) {
super(price, desc);
}
}
두 버거에 같은 매개변수를 이용하는 생성자 오버로딩이므로, 부모 클래스인 burger의 내용을 사용할 것이므로 super을 이용한다.
햄버거는 세트가 있다.
햄버거 세트는 콜라와 감자튀김도 있다. 이 클래스도 만들어보자.
- 콜라
import lombok.Data;
@Data
public class Coke {
private int price;
private String desc;
public Coke() {
this(1500, "코카콜라");
}
public Coke(int price, String desc) {
this.price=price;
this.desc=desc;
System.out.println(desc+"가 만들어졌습니다.");
}
}
- 감자튀김
import lombok.Data;
@Data
public class FrenchFried {
private int price;
private String desc;
public FrenchFried() {
this(2000,"감자칩");
}
public FrenchFried(int price, String desc) {
this.price=price;
this.desc=desc;
System.out.println(desc+"가 만들어졌습니다.");
}
}
이제 세트를 만들것이다.
하지만 세트는 문제가 있다. 햄버거 세트는 햄버거라고 부를 수가 없다.
이렇게 다형성이 사라진 경우, 기존의 클래스들을 컴포지션으로 묶을 수 있다.
햄버거 세트를 만드는 클래스를 보자.
import lombok.Data;
@Data
public class BigBurgerSet {
private Bigburger bigburger;
private Coke coke;
private FrenchFried frenchFried;
public BigBurgerSet() {
this(
new Bigburger(),
new Coke(),
new FrenchFried()
);
}
public BigBurgerSet(Bigburger bigburger2) {
this.getBigburger();
}
public BigBurgerSet(Bigburger bigburger, Coke coke, FrenchFried frenchFried) {
this.bigburger = bigburger;
this.coke = coke;
this.frenchFried = frenchFried;
}
}
BigBurgerSet에서 private를 이용해 세 개의 클래스를 재사용 하고 있는데, 이걸 컴포지션이라고 할 수 있다.
이후 생성자와 this를 통해 클래스 내부의 값을 리턴한다.
다음 최종적으로 값을 리턴할 코드를 보자.
public class LotteriaApp {
public static void main(String[] args) {
BigBurgerSet set1=new BigBurgerSet();
new BigBurgerSet(
new Bigburger(3000,"빅버거 할인"),
new Coke(),
new FrenchFried()
);
BigBurgerSet set3=
new BigBurgerSet(
new Bigburger(2000, "빅버거 할인")
);
}
}
다양한 방식으로 빅버거 세트를 만들어보았다.
클래스 호출 형식과, 선언한대로 매서드 내의 매개변수를 다 집어넣거나, 혹은 오버로딩을 이용해 클래스 내에 빅버거 타입의 매개변수를 선언해 get 매서드를 통해 호출하는 방식도 있다.
따라서, 컴포지션은 매서드를 재사용하기 위해 만든다는 것!
'JAVA' 카테고리의 다른 글
JAVA 실습 8. 객체 지향, 제네릭과 컬렉션을 이용한 커피숍 만들기. (0) | 2020.04.03 |
---|---|
Warpper 클래스와 제네릭 기초 (0) | 2020.04.03 |
11. 인터페이스 (0) | 2020.03.31 |
10. 추상 클래스/추상 매서드 (0) | 2020.03.31 |
라이브러리(lombok) 설치하기 (0) | 2020.03.31 |