인터페이스는 다중 상속의 한계를 극복하기 위해 사용할 수 있다.
상속은 is a kind of 관계이고
인터페이스는 be able to 관계이다.
따라서 아래와 같이 형제 관계에 있는 고래와 펭귄의 '헤엄칠 수 있는'과 관련된 요소들을 공통적으로 관리할 수 있다.
참고 - 상속
클래스를 선언할 때 인터페이스는 필드
, 생성자/메소드의 매개 변수
, 생성자/메소드의 로컬 변수
로 선언될 수 있다.
인터페이스가 필드/매개변수/로컬변수로 선언되면 구현 객체를 생성하여 대입한다.
public class MyClass {
//필드
RemoteControl rc = new Television();
//생성자의 매개변수
MyClass(RemoteControl rc) { //생성자의 매개값으로 구현객체 대입
this.rc = rc;
}
//메소드의 로컬변수
void methodA() {
RemoteControl rc = new Audio();
}
//메소드의 매개변수
void methodB(RemoteControl rc){...} //메소드 호출 시 구현 객체를 매개값으로 대입
}
RemoteControl rc = new Television();
MyClass mc = new MyClass(new Television());
RemoteControl rc = new Audio();
mc.methodB(new Audio());
인터페이스를 사용하면, 구현 객체를 손쉽고 빠르게 교체할 수 있다
기존 구현 객체에 문제가 발생 시 새로운 구현 객체를 생성 후 변경하기 때문에 코드 수정이 최소화된다.
하나의 구현객체에서 여러 개의 인터페이스를 구현하는 것
public interface 고래 {
void 고래수영();
}
public interface 펭귄 {
void 펭귄수영();
}
public class 수영구현 implements 고래, 펭귄{
public void 고래수영() {
sout("고래가 수영합니다");
}
public void 펭귄수영(){
sout("펭귄이 수영합니다");
}
}
---
public class 수영장{
public static void main(String[] args){
//수영구현 객체 생성
수영구현 수영구현 = new 수영구현();
고래 흰수염고래 = 수영구현;
펭귄 황제펭귄 = 수영구현;
}
}
다중 구현의 상황에서 동일한 추상메서드가 있을 때, 충돌을 해결할 수 있는 방법은 무엇일까?
만약 고래와 펭귄 인터페이스에 동일한 수영() 메소드가 있다고 할 때 어떻게 구현할 수 있을까?
public interface InterfaceA {
public void methodA();
}
public interface InterfaceB {
public void methodB();
}
public interface InterfaceC {
public void methodC();
}
public class ImplementationC implements InterfaceA, InterfaceB {
// ...
}
3개의 인터페이스 타입의 변수에 C 클래스 구현 객체를 대입하면, 각 객체들은 각 인터페이스의 메서드를 사용할 수 있다.
즉, 하나의 구현 객체를 통해 다양한 인터페이스 타입의 객체들이 관리될 수 있다.
public interface 고래 {
public void 수영();
}
public interface 펭귄 {
public void 수영();
public void 얼음깨기();
}
public interface 헤엄칠수있는 extends 고래, 펭귄 {
public void 물뿜기();
}
public class 헤엄칠수있는구현체 implements 헤엄칠수있는 {
@Override
public void 수영() {
// 고래 수영()에 대한 구현
고래.super.수영(); // 고래의 수영() 호출
// 또는 펭귄.super.수영(); // 펭귄의 수영() 호출
}
@Override
public void 펭귄() {
// 펭귄의 얼음깨기()에 대한 구현
}
@Override
public void 물뿜기() {
// 헤엄칠수있는의 물뿜기()에 대한 구현
}
}