인터페이스의 이해
1. 인터페이스의 이해 서두
먼저 인터페이스를 이해하기 위해서는 다음의 두 가지 사항을 반드시 염두에 두고 있어야 한다.
1) 클래스를 사용하는 쪽(User)과 클래스를 제공하는 쪽(Provider)이 있다.
2) 메서드를 사용(호출)하는 쪽(User)에서는 사용하려는 메서드(Provider)의 선언부만 알면 된다. (내용은 몰라도 된다.)
class A{
public void method( B b){
b.method();
}
}
class B {
public void methodB(){
System.out.println("methodB()");
}
}
class InterfaceTest{
public static void main(String args[]){
A a = new A();
a.methodA(new B());
}
}
-------------------------------------
실행결과
methodB()
클래스 A(User)는 클래스 B(Provider)의 인스턴스를 생성하고 메서드를 호출한다. 이 두 클래스는 서로 직접적인 관계에 있다. 이것을 간단히 'A(User)-->B(Provider)'라고 표현하다.
이 경우 클래스 A를 작성하기 위해서는 클래스 B가 이미 작성되어 있어야 한다. 그리고 클래스의 B의 methodB()의 선언부가 변경되면, 이를 사용하는 클래스 A도 변경되어야 한다.
이와 같이 직접적인 관계의 두 클래스는 한쪽(Provider)이 변경되면 다른 한 쪽(User)도 변경되어야 한다는 단점이 있다.
그러나 클래스 A가 클래스 B를 직접 호출하지 않고 인터페이스를 매개체로 해서 클래스 A가 인터페이스를 통해서 클래스 B의 메서드에 접근하도록 하면, 클래스 B에 변경사항이 생기거나 클래스 B와 같은 기능의 다른 클래스로 대체 되어도 클래스 A는 전혀 영향을 받지 않도록 하는 것이 가능하다.
2. 두 클래스간의 관계를 간접적으로 변경하기
두 클래스간의 관계를 간접적으로 변경하기 위해서는 먼저 인터페이스를 이용해서 클래스B(Provider)의 선언과 구현을 분리해야 한다.
먼저 다음과 같이 클래스 B에 정의된 메서드를 추상메서드로 정의하는 인터페이스 I를 정의한다.
interface I {
public abstract void methodB();
}
그 다음에는 클래스 B가 인터페이스 I를 구현하도록 한다.
class B implements I {
public void methodB(){
System.out.println("methodB in class");
}
}
이제 클래스 A는 클래스 B 대신 인터페이스 I를 사용해서 작성할 수 있다.
class A {
public void methodA(I i){
i.methodB();
}
}
cf.) methodA가 호출될 때 인터페이스 I를 구현한 클래스의 인스턴스(클래스 B의 인스턴스)를 제공받아야 한다.
--> 클래스 A를 작성하는데 있어서 클래스 B가 사용되지 않았다는 점에 주목하자. 이제 클래스 A와 클래스 B는 'A-B'의 직접적인 관계에서 'A-I-B'의 간접적인 관계로 바뀐 것이다.
결국 클래스 A는 여전히 클래스 B의 메서드를 호출하지만, 클래스 A는 인터페이스 I하고만 직접적인 관계에 있기 때문에 클래스 B의 변경에 영향을 받지 않는다.
클래스 A는 인터페이스를 통해 실제로 사용하는 클래스의 이름을 몰라도 되고 심지어는 실제로 구현된 클래스가 존재하지 않아도 문제되지 않는다. 클래스 A는 오직 직접적인 관계에 있는 인터페이스의 I의 영향만 받는다.
인터페이스 I는 실제 구현 내용(클래스 B)을 감싸고 있는 껍데기이며, 클래스 A는 껍데기안에 어떤 알맹이(클래스)가 들어 있는지 몰라도 된다.
class A {
void autoPlay(I i) {
i.play();
}
}
interface I {
public abstract void play();
}
class B implements I {
public void play() {
System.out.println("play in B class");
}
}
class C implements I {
public void play() {
System.out.println("play in C class");
}
}
class InterfaceTest2 {
public static void main(String[] args) {
A a = new A();
a.autoPlay(new B());
a.autoPlay(new C());
}
}
---------------------------------------
실행결과
play in B class
play in C class
클래스 A가 인터페이스 I를 사용해서 작성되긴 하였지만, 이처럼 매개변수를 통해서 인터페이스 I를 구현한 클래스의 인스턴스를 동적으로 제공받아야 한다.
'Programing > Java' 카테고리의 다른 글
[Java] 변수의 종류 (0) | 2014.12.14 |
---|---|
[Java] abstract (0) | 2014.12.11 |
[Java] 형변환 (0) | 2014.12.02 |
[Java] 실행 (0) | 2014.12.02 |
[Java] Java SE, JDK, JRE (0) | 2014.12.02 |