[JAVA] 인터페이스
인터페이스는 아주 중요한 개념. 인터페이스에 대한 개념 없이 코드로만 이해하려고 하면 곧 미궁에 빠지게 된다.
다음의 경우를 코드로 작성해 보자.
난 동물원의 사육사이다.
육식동물이 들어오면 난 먹이를 던져준다.
호랑이가 오면 사과를 던져준다.
사자가 오면 바나나를 던져준다.
Animal.java
public class Animal {
String name;
public void setName(String name) {
this.name = name;
}
}
Tiger.java
public class Tiger extends Animal {
}
Lion.java
public class Lion extends Animal {
}
ZooKeeper.java
public class ZooKeeper {
public void feed(Tiger tiger) {
System.out.println("feed apple");
}
public void feed(Lion lion) {
System.out.println("feed banana");
}
public static void main(String[] args) {
ZooKeeper zooKeeper = new ZooKeeper();
Tiger tiger = new Tiger();
Lion lion = new Lion();
zooKeeper.feed(tiger);
zooKeeper.feed(lion);
}
}
feed apple
feed banana
동물원에 호랑이와 사자뿐이라면 ZooKeeper 클래스는 완벽하겠지만 악어, 표범 등이 계속 추가된다면 ZooKeeper는 육식동물이 추가될 때마다 매번 다음과 같은 feed 메서드를 추가해야 한다.
...
public void feed(Crocodile crocodile) {
System.out.println("feed strawberry");
}
public void feed(Leopard leopard) {
System.out.println("feed orange");
}
...
이렇게 동물이 추가 될 때마다 feed 메서드를 추가하기란 매우 귀찮다......
이를 해결하기 위해서 인터페이스를 사용!
Predator.java
public interface Predator {
}
Tiger.java
public class Tiger extends Animal implements Predator {
}
Lion.java
public class Lion extends Animal implements Predator {
}
Tiger, Lion이 Predator 인터페이스를 구현하면 ZooKeeper 클래스의 feed 메서드를 다음과 같이 변경할 수 있다.
변경 전
public void feed(Tiger tiger) {
System.out.println("feed apple");
}
public void feed(Lion lion) {
System.out.println("feed banana");
}
변경 후
public void feed(Predator predator) {
System.out.println("feed apple");
}
feed 메서드의 입력으로 Tiger, Lion을 각각 필요로 했지만 이제 이것을 Predator라는 인터페이스로 대체할 수 있게 되었다. tiger, lion은 각각 Tiger, Lion의 객체이기도 하지만 Predator 인터페이스의 객체이기도 하기 때문에 위와 같이 Predator를 자료형의 타입으로 사용할 수 있는 것이다.
자, 그런데 위 ZooKeeper 클래스에 약간의 문제가 발생했다. 아래의 ZooKeeper클래스의 feed 메서드를 보면 호랑이가 오던지, 사자가 오던지 무조건 "feed apple" 이라는 문자열을 출력한다. 사자가 오면 "feed banana" 를 출력해야 하지 않겠는가!
Predator.java
public interface Predator {
public String getFood();
}
Tiger.java
public class Tiger extends Animal implements Predator {
public String getFood() {
return "apple";
}
}
Lion.java
public class Lion extends Animal implements Predator {
public String getFood() {
return "banana";
}
}
ZooKeeper.java
public class ZooKeeper {
public void feed(Predator predator) {
System.out.println("feed "+predator.getFood());
}
}
위와 같이 동물의 종류만큼 feed 메소드를 사용하는 대신, Predator 인터페이스를 이용하여 단 하나의 feed 메소드로 구현 가능해졌다.