어떤 부모의 move()를 사용해야 할지 애매한 문제가 발생 -> 다이아몬드 문제이다.
다중 상속을 사용하면 클래스 계층 구조가 매우 복잡해진다.
인터페이스는 다중 구현을 허용한다.
인터페이스는 모두 추상 메서드로 이루어져 있다.
기능은 자식에만 있다.
클래스 상속과 인터페이스 구현을 함께 사용
AbstractAnimal은 추상 클래스이다.
soun() : 동물의 소리를 내기 위한 sound() 추상 메서드를 제공한다.
public class Bird extends AbstractAnimal implements Fly{
@Override
public void sound() {
System.out.println("짹쨱");
}
@Override
public void fly() {
System.out.println("새 날기");;
}
}
인터페이스는 무한정으로 구현할 수 있다.
public class SoundFlyMain {
public static void main(String[] args) {
Dog dog = new Dog();
Bird bird = new Bird();
Chicken chicken = new Chicken();
soundAnimal(dog);
soundAnimal(bird);
soundAnimal(chicken);
flyAnimal(bird); // 추상 애니멀 타입도 되고, fly타입도 된다.
flyAnimal(chicken);
}
// AbstractAnimal 사용 가능
private static void soundAnimal(AbstractAnimal animal){
System.out.println("동물 소리 테스트 시작");
animal.sound();
System.out.println("동물 소리 테스트 종료");
}
// Fly 인터페이스가 있으면 사용 가능
private static void flyAnimal(Fly fly){
System.out.println("날기 테스트 시작");
fly.fly();
System.out.println("날기 테스트 종료");
}
}