728x90

참고 강의 : https://wikidocs.net/book/31

 

 

인터페이스

 

인터페이스의 필요성

 

육식 동물에게 먹이를 주는 사육사(ZooKeeper) 클래스가 있다고 하자. 그리고 Animal 클래스를 상속하는 Tiger와 Lion 클래스가 있다.

 

ZooKeeper 클래스의 feed 메소드는 메소드 오버로딩 되어 있다. (입력값이 각각 Tiger, Lion으로 자료형이 다름)

1
2
3
4
5
6
7
8
9
public class ZooKeeper {    
    public void feed(Tiger tiger) {
        System.out.println("feed tiger");
    }
 
    public void feed(Lion lion) {
        System.out.println("feed lion");
    }
}
cs

 

하지만 이 경우, Animal을 상속하는 새로운 동물 클래스가 생길 때 마다, ZooKeeper에도 feed 메소드가 필요하게 된다.

 

이럴때 필요한 것이 바로 "인터페이스"이다.

 

 


 

Predator.java

 

1
2
public interface Predator {
}
cs

육식 동물 인터페이스를 작성했다. class 키워드가 아닌 interface 키워드를 사용해 구현한다.

 

그리고 Tiger와 Lion 클래스는 Animal 클래스를 사용하며, Predator 인터페이스를 구현하도록 한다. 이 때는 implements라는 키워드를 사용한다.

1
2
public class Tiger extends Animal implements Predator {    
}
cs

 

1
2
public class Lion extends Animal implements Predator { 
}
cs

 

이제부터는 어떤 육식 동물이 추가되더라도 다음과 같이 인터페이스를 구현한 클래스를 정의하면 된다.

1
2
public class Crocodile extends Animal implements Predator {
}
cs

 

하지만 아직도 문제는 있다. 

1
2
3
public void feed(Predator predator) {
    System.out.println("feed ???");
}
cs

 

ZooKeeper 클래스가 육식동물(클래스)의 이름(name)에 따라 다른 문자열을 출력해야 할 것이다.

 

이럴 때 인터페이스에 새로운 메소드 추가가 필요하다.

 


 

Predator.java

 

1
2
3
public interface Predator {
    public String getName();
}
cs

위에서 특이한 점은 getName 메소드에 몸통(body)가 없다는 점이다. 보통은 메소드명(입력값) { 몸통 } 으로 정의되어야 할 것인데 말이다.

이것은 인터페이스의 규칙으로 위의 getName이라는 메소드는, 다음과 같이 인터페이스를 implements한 클래스들이 구현해야 한다.

 

1
2
3
4
5
public class Tiger extends Animal implements Predator {
    public String getName() {
        return this.name;
    }
}
cs

 

이제 ZooKeeper 클래스의 feed 메소드를 다음과 같이 정의하면 육식동물의 이름에 따라 다른 문자열을 출력할 것이다.

1
2
3
4
5
public class ZooKeeper {    
    public void feed(Predator predator) {
        System.out.println("feed "+predator.getName());
    }
}
cs

predator.getName()을 호출하면, Predator 인터페이스를 구현한 구현체(Tiger, Lion)의 getName()이 호출된다.

 

 

Tiger와 Lion에 있는 getName 메소드가 중복되어 있으므로, 제거하고 Animal 클래스에 getName 메소드를 구현하도록 한다. 

(육식동물 클래스는 Animal클래스를 상속받으니깐)

이렇게 중복된 메소드를 제거하고, 이동하는 행위를 리팩토링(Refactoring)이라고 한다.

 

메인 메소드도 다음과 같이 정의하고 실행결과를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ZooKeeper {    
    public void feed(Predator predator) {
        System.out.println("feed "+predator.getName());
    }
 
    public static void main(String[] args) {
        Tiger tiger = new Tiger();
        tiger.setName("tiger");
 
        Lion lion = new Lion();
        lion.setName("lion");
 
        ZooKeeper zooKeeper = new ZooKeeper();
        zooKeeper.feed(tiger);
        zooKeeper.feed(lion);
    }
}
cs

Output : 

feed tiger

feed lion

 

 

인터페이스의 개념적인 이해

 

컴퓨터의 USB 포트에는 다양한 기기를 연결할 수 있다. 바로 이 USB포트가 물리적 세계의 인터페이스라고 할 수 있다.

USB포트의 규격만 알면 어떤 기기도 만들 수 있고, 컴퓨터는 USB 포트만 제공하고 어떤 기기가 만들어지는 지 신경쓸 필요가 없다. 바로 이 점이 인터페이스의 핵심이다.

 

위에서 만든 사육사(ZooKeeper) 클래스가 호랑이던 사자던 상관하지 않고 먹이를 줄 수 있는것과 같다.

물리적세계 자바세계
컴퓨터 ZooKeeper
USB 포트 Predator
하드디스크, 디지털카메라,... Tiger, Lion, Crocodile,...

※ USB 포트에는 전자기기들이 지켜야만 하는 각종 규칙들이 있다. (인터페이스의 메소드)

'Study > Java' 카테고리의 다른 글

Java Network 프로그래밍 기초  (0) 2017.06.03
NIO 기반 네트워킹  (0) 2017.05.30
JAVA - NIO  (0) 2017.05.29
Java - OOP_클래스와 상속, 생성자, 오버로딩/오버라이딩  (0) 2017.03.17
Java 개발PC 설정 및 기초  (0) 2017.03.16

+ Recent posts