JavaRush /Java Blog /Random-KO /Java의 상속과 구성
dio
레벨 16
Москва

Java의 상속과 구성

Random-KO 그룹에 게시되었습니다
이 기사에서는 Java의 상속 및 구성 개념을 설명합니다. 첫 번째 예에서는 상속을 설명한 다음 구성을 사용하여 상속 디자인을 개선하는 방법을 보여줍니다. 마지막에 그 중에서 선택하는 방법을 요약하겠습니다. Java의 상속과 구성 - 1

1. 상속

Insect클래스 (영어 곤충)가 있다고 가정해 보겠습니다. 이 클래스에는 1. move()(영어 이동에서) 및 2. attack()(영어 공격에서) 의 두 가지 메서드가 포함되어 있습니다.
class Insect {
	private int size;
	private String color;

	public Insect(int size, String color) {
		this.size = size;
		this.color = color;
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public void move() {
		System.out.println("Move");
	}

	public void attack() {
		move(); //assuming an insect needs to move before attacking
		System.out.println("Attack");
	}
}
Bee이제 유형 중 하나이지만 및 의 Insect구현이 다른 클래스(English bee)를 정의하려고 합니다 . 이는 상속을 사용하여 수행할 수 있습니다. attack()move()
class Bee extends Insect {
	public Bee(int size, String color) {
		super(size, color);
	}

	public void move() {
		System.out.println("Fly");
	}

	public void attack() {
		move();
		super.attack();
	}
}
public class InheritanceVSComposition {
	public static void main(String[] args) {
		Insect i = new Bee(1, "red");
		i.attack();
	}
}
클래스 계층 다이어그램은 매우 간단합니다. Java의 상속과 구성 - 2실행 결과:
Fly
Fly
Attack
"Fly"가 두 번 입력되었으므로 메서드가 move()두 번 호출됩니다. 하지만 한 번만 호출해야 합니다. 문제는 super.attack(). 메소드는 클래스 메소드를 attack ()호출합니다 . 하위 클래스가 호출할 때 재정의된 메서드도 호출합니다 . 문제를 해결하기 위해 다음을 수행할 수 있습니다. move()Insectsuper.attack ()move()
  1. 하위 클래스 메서드를 제거합니다 attack(). 이렇게 하면 하위 클래스가 상위 클래스의 메서드 구현에 종속되게 됩니다 attack(). 슈퍼클래스가 다른 이동 방법을 사용하기 시작 하면 attack()attack()서브클래스도 변경해야 합니다. 이것은 잘못된 캡슐화입니다.
  2. 메소드를 attack()다음과 같이 다시 작성하십시오.

    public void attack() {
    	move();
    	System.out.println("Attack");
    }
  3. 이는 하위 클래스가 더 이상 상위 클래스에 종속되지 않기 때문에 올바른 결과를 보장합니다. 그러나 코드는 슈퍼클래스와 중복됩니다. (이 메소드는 attack()단순히 문자열을 출력하는 것보다 더 복잡한 작업을 수행합니다). 이는 좋은 소프트웨어 설계가 아니며 중복된 코드가 없어야 합니다.

이 상속 설계는 하위 클래스가 상위 클래스의 구현 세부 사항에 의존하기 때문에 좋지 않습니다. 슈퍼클래스가 변경되면 하위클래스가 올바르게 작동하지 않습니다.

2. 구성

상속 대신 합성을 사용할 수 있습니다. 이를 활용한 솔루션을 살펴보겠습니다. 함수는 attack()인터페이스로 추상화됩니다.
interface Attack {
	public void move();
	public void attack();
}
공격 인터페이스를 구현하여 다양한 유형의 공격을 정의할 수 있습니다.
class AttackImpl implements Attack {
	private String move;
	private String attack;

	public AttackImpl(String move, String attack) {
		this.move = move;
		this.attack = attack;
	}

	@Override
	public void move() {
		System.out.println(move);
	}

	@Override
	public void attack() {
		move();
		System.out.println(attack);
	}
}
공격 기능은 외부이므로 클래스에 Insect더 이상 포함되지 않습니다.
class Insect {
	private int size;
	private String color;

	public Insect(int size, String color) {
		this.size = size;
		this.color = color;
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
}
클래스 Bee(English Bee에서), 공격 유형이 어떻게 Insect될 수 있는지.
// This wrapper class wrap an Attack object
class Bee extends Insect implements Attack {
	private Attack attack;

	public Bee(int size, String color, Attack attack) {
		super(size, color);
		this.attack = attack;
	}

	public void move() {
		attack.move();
	}

	public void attack() {
		attack.attack();
	}
}
클래스 다이어그램: Java의 상속과 구성 - 3
public class InheritanceVSComposition2 {
	public static void main(String[] args) {
		Bee a = new Bee(1, "black", new AttackImpl("fly", "move"));
		a.attack();

		// if you need another implementation of move()
		// there is no need to change Insect, we can quickly use new method to attack

		Bee b = new Bee(1, "black", new AttackImpl("fly", "sting"));
		b.attack();
	}
}
실행 결과:
fly
move
fly
sting

3. 이러한 접근 방식을 언제 사용해야 합니까?

다음 2가지 사항은 상속과 구성 사이를 결정하는 데 도움이 될 수 있습니다.
  1. "IS" 형식의 클래스 간의 관계를 처리하고 클래스가 모든 인터페이스를 다른 클래스에 제공하려는 경우 상속이 더 좋습니다.
  2. 관계가 "HAS"이면 구성이 선호됩니다.
따라서 상속과 구성에는 고유한 용도가 있으며 그 장점을 이해하는 것이 좋습니다. 연결:
  1. 블로흐, 조슈아. 효과적인 자바. 피어슨 교육 인도, 2008
  2. https://stackoverflow.com/questions/49002/prefer-composition-over-inheritance
  3. https://www.javaworld.com/article/2076814/core-java/inheritance-versus-composition--which-one-should...
원본 기사 링크
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION