본문 바로가기
아카이브/자바의 정석

7장 20200926

by nineteen 2020. 9. 26.
반응형

인터페이스의 장점

 

- 개발시간을 단축시킬 수 있다

- 표준화가 가능

- 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있음

- 독립적인 프로그래밍 가능

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package interfacesex;
 
interface Repairable {
}
 
class Unit {
    int hitPoint;
    final int MAX_HP;
    Unit(int hp) {
        MAX_HP = hp;
    }
}
 
class GroundUnit extends Unit {
    GroundUnit(int hp) {
        super(hp);
    }
}
 
class AirUnit extends Unit {
    AirUnit(int hp) {
        super(hp);
    }
}
 
class Tank extends GroundUnit implements Repairable {
    Tank() {
        super(150);
        hitPoint = MAX_HP;
    }
    
    public String toString() {
        return "Tank";
    }
}
 
class Dropship extends AirUnit implements Repairable {
    Dropship() {
        super(125);
        hitPoint = MAX_HP;
    }
    
    public String toString() {
        return "Dropship";
    }
}
 
class Marine extends GroundUnit {
    Marine() { 
        super(40);
        hitPoint = MAX_HP;
    }
}
 
class SCV extends GroundUnit implements Repairable {
    SCV() {
        super(60);
        hitPoint = MAX_HP;
    }
    
    // 인터페이스를 매개변수로 받음, 
    // 인터페이스가 구현된 클래스만 접근가능
    // 인터페이스로 특정클래스들에 공통점부여가능
    void repair(Repairable r) {
        if(r instanceof Unit) {
            Unit u = (Unit)r; // Unit클래스로 형변환해 hitPoint, MAX_HP사용
            while(u.hitPoint != u.MAX_HP) {
                u.hitPoint++;
            }
            System.out.println(u.toString() + "의 수리가 끝났습니다.");
        }
    }
}
 
package interfacesex;
public class RepairableTest {
    public static void main(String[] args) {
        Tank tank = new Tank();
        Dropship dropship = new Dropship();
        
        Marine marine = new Marine();
        SCV scv = new SCV();
        
        scv.repair(tank);
        scv.repair(dropship);
        scv.repair(scv); // toString()메소드 정의 x -> 주소가 출력
        //scv.repair(marine);  ->  에러, Marine에 Repairable인터페이스 정의x
    }
}
 
 
 
 
cs

출력

Tank의 수리가 끝났습니다.
Dropship의 수리가 끝났습니다.

interfacesex.SCV@153f5a29의 수리가 끝났습니다.

 

 

 

p391 ~ 396 읽어보기

 

특정클래스들에 인터페이스구현 -> 특정클래스들에 공통점부여 -> 인터페이스가 구현된 클래스들만 사용가능한 메소드 구현, 사용가능

 

 

 

인터페이스작성 -> 인터페이스구현된 클래스 작성 -> 특정 클래스에 인터페이스 상속 / 인터페이스 구현된 클래스를  특정 클래스의 멤버로 구성

 

 

 

 

 

 

 

 

 

 

인터페이스의 이해

 

- 클래스를 사용하는 쪽(User)과 클래스를 제공하는 쪽(Provider)이 있다

- 메소드를 사용(호출)하는 쪽(User)에서는 사용하려는 메소드(Provider)의 선언부만 알면된다 (내용 몰라도됨)

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package interfacesex;
 
class A {
    public void methodA(B b) {
        b.methodB();
    }
}
 
class B {
    public void methodB() {
        System.out.println("methodB()!");
    }
}
 
public class InterfaceTest {
    public static void main(String[] args) {
        A a = new A();
        a.methodA(new B()); // methodA()를 실행하기 위해 B클래스 인스턴스 필요
    }
}
 
cs

출력

methodB()!

 

 

 

클래스A(User)는 클래스B(Provider)의 인스턴스를 생성하고 메소드 호출

 

클래스A를 작성하려면 클래스B가 이미 작성되어 있어야 하고,

클래스B의 methodB()선언부가 변경되면 클래스A도 변경되야하는 단점이 있음

 

클래스A가 클래스B를 직접 호출하지 않고 인터페이스를 매개체로 해서

클래스A가 인터페이스를 통해 클래스B의 메소드에 접근하게하면, 클래스B에 변경사항이 있어도

클래스A는 영향받지 않음

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package interfacesex;
 
interface I {
    void play();
}
 
class A {
    // 인터페이스의 메소드 호출
    public void autoPlay(I i) {
        i.play();
    }
}
 
// I인터페이스 구현
class B implements I {
    public void play() {
        System.out.println("play in B class");
    }
}
 
//I인터페이스 구현
class C implements I {
    public void play() {
        System.out.println("play in C class");
    }
}
 
 
public class InterfaceTest {
    public static void main(String[] args) {
        A a = new A();
        a.autoPlay(new B()); // I를 구현한 B클래스의 play()메소드 실행
        a.autoPlay(new C()); // I를 구현한 C클래스의 play()메소드 실행
    }
}
 
cs

출력

play in B class
play in C class

 

 

 

클래스A를 작성하는데 클래스B가 사용되지 않았음

클래스A와 클래스B는 'A-B' 직접적 관계에서 'A-I-B'의 간접적 관계로 바뀜

 

클래스A는 여전히 클래스B의 메소드를 호출하지만,

인터페이스I하고만 직접적인 관계이기 때문에 클래스B의 변경에 영향받지않음

 

인터페이스I는 실제구현 내용(클래스B,C)을 감싸고 있는 껍데기이며,

클래스A는 껍데기안에 어떤 알맹이(클래스)가 들어있는지 몰라도 된다

'아카이브 > 자바의 정석' 카테고리의 다른 글

8장 예외처리 20201012  (0) 2020.10.12
8장 예외처리 20201009  (0) 2020.10.09
7장 20200925  (0) 2020.09.25
7장 20200924  (0) 2020.09.24
7장 상속 20200921  (0) 2020.09.21