interface Repairable {}
class GroundUnit extends Unit {
GroundUnit(int hp) {
super(hp);
}
}
class AirUnit extends Unit {
AirUnit(int hp) {
super(hp);
}
}
class Unit {
int hitPoint;
final int MAX_HP;
Unit(int hp)
MAX_HP = hp;
}
}
모든 유닛의 최고 조상 class Unit 정의
Unit class를 조상으로 하는 class ( GroundUnit, AirUnit )를 정의
interface Repairable 를 통해서 해당 유닛이 수리가 가능한지 알려주는데 사용
class Tank extends GroundUnit implements Repairable {
Tank() {
super(150);
hitPoint = MAX_HP;
}
public String toString() {
return "Tank";
}
}
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;
while(u.hitPoint != u.MAX_HP) {
u.hitPoint++;
}
}
}
}
repair( )메서드의 매개변수의 타입을 모든 유닛의 수리가 가능한게 아니기 때문에
Unit, AirUnit, GroundUnit 할 수 없다.
그렇기 때문에 수리가 가능한 유닛은 implements Repairable 인터페이스를 구현하도록 한다.
repair 메서드의 매개변수의 타입을 Repairable 인터페이스로 하면 Repairable 인터페이스를 구현한 클래스의 인스턴스만 사용가능하게 된다.
public static void main(String[] args) {
Tank tank = new Tank();
Marine marine = new Marine();
SCV scv = new SCV();
scv.repair(tank); //SCV가 Tank를 수리한다.
scv.repair(marine); //에러 !!!
interface Repairable {}
-------------------------
void repair(Repairable r) {
if (r instanceof Unit) {
Unit u = (Unit)r;
while(u.hitPoint != u.MAX_HP) {
u.hitPoint++;
}
}
}
매개변수로 Repairable의 인스턴스를 받고난 뒤 인터페이스는 아무런 구현된게 없기 때문에 instanceof로 형변환 할 수 있는지 확인 절차를 거친 다음 형변환하여 수리하는 기능을 하게 된다.
그래서 인터페이스의 장점은 관계가 없는 class들을 묶어주는 역할을 할 수 있다는 것 같다.
두 클래스 간에 간접적인 관계라서 한개가 변해도 영향을 받지 않는다.
개발 시간을 단축시킨다.
//직접적인 관계의 두 클래스(A-B)
class A {
public void load(B b) {
b.character();
}
}
class B {
public void character() {
System.out.println("캐릭터를 불렀다~~~!");
}
}
class InterfaceTest {
public static void main(String args[]) {
A a = new A();
a.load(new B());
}
}
----------------------------------------------
// 간접적인 관계의 두 클래스(A-I-B)
class A {
public void load(I i) {
i.character();
}
}
interface I { void character(); }
class B implements I {
public void character() {
System.out.println("캐릭터를 불렀다~~~!");
}
}
class C implements I {
public void character() {
System.out.println("캐릭터를 불렀다~~~!");
}
}
선언과 구현을 분리
class B에 정의된 character()메서드들의 선언부만 뽑아서 interface에 정의하고 class B가 정의한 interface를 구현하도록 하는 것을 말함.
class A가 class B 대신 interface I를 매개변수로 사용하도록 변경한다.
이렇게 됨으로써 class B의 수정의 영향이 class A에 영향을 미치지 않게 된다.
(그래서 새로운 class C의 메서드를 불러올 때도 수정할 필요없이 불러올 수 있다.)
매개변수의 타입이 interface I 라는 것은 인터페이스 I를 구현한 클래스 인스턴스라면 어떤것이라도 매개변수로 가능하다.