2017-10-25 21 views
3

가정하자 내가 가지고있는 다음과 같은 인터페이스와 구현이 같은getClass

interface Weapon{ 
    int attack(); 
} 

public class Sword implements Weapon { 

    //Constructor, and Weapon interface implementation 
    //... 
    public void wipeBloodfromSword(){} 
} 


public class ChargeGun implements Weapon { 
    //Constructor, and Weapon interface implementation 
    //... 
    public void adjustlasersight(){} 
} 

하고이를 저장 :

List<Weapon> weaponInventory = new ArrayList<Weapon>(); 
weaponInventory.add(new Sword()); 
weaponInventory.add(new ChargeGun()); 

문제 :

그들이 List<Weapon>에 저장되어 있다고 가정하면 나는 분명히에 선언 된 메소드에만 액세스 할 수 있습니다.interface. downcasting이고 instanceof/getClass()의 사용을 피해야하는 경우 클래스 특정 방법 wipeBloodfromSword()adjustlasersight()에 액세스하려면 어떻게해야합니까?

가능한 해결 방법 :

공격 메서드가 호출 된 후, 나는이처럼 내 인터페이스를 다시 쓰기 전에 행동이 있다는 것을 감안할 때 :

interface Weapon{ 

    //Can reload a weapon, adjust a laser sight 
    //do anything to the weapon to prepare for an attack 
    void prepareWeapon(); 
    int attack(); 
    //Not sure of a more proper name, 
    //but you can wipe blood off sword or take off silencer 
    void postAttackActions(); 
} 

동안, 나는에있어 이 취미 프로젝트를 제어하면 interface을 변경할 수없는 상황이 발생할 수 있으며 interface은이 특정 문제를 해결할 수 있습니다. interface을 그대로 두어야한다면 어떻게해야합니까?

+0

"어떻게해야합니까?"라는 질문은 좋은 유형이 아닙니다. –

+1

인터페이스를 변경할 수 없다면 * instanceof 또는 reflection을 사용해야합니다. 그러나 정답은 인터페이스를 변경하는 것입니다. –

+0

정적 클래스가 정답이 아닙니까 ??? –

답변

2

를 검 또는 ChargeGun로 목록 항목을 캐스팅하고 입력 할 수 있습니다.

class WeaponVisitor { 
    void visit(Sword aSword) { } 
    void visit(ChargeGun aGun) { } 
} 

// add accept method to your Weapon interface 
interface Weapon { 
    ... 
    void accept(Visitor v); 
} 

// then implement accept in your implementing classes 
class Sword { 
... 
    @Override 
    void accept(Visitor v) { 
     v.visit(this); // this is instanceof Sword so the right visit method will be picked 
    } 
} 

// lastly, extend Visitor and override the methods you are interested in 
class OnlySwordVisitor extends Visitor { 
    @Override void visit(Sword aSword) { 
     System.out.println("Found a sword!"); 
     aSword.wipeBloodfromSword(); 
    } 
} 
+0

Wonderful,'downcasting','instanceof' 또는 getClass()를 사용할 필요가 없습니다 –

+0

가능하면'void accept (Visitor (WeaponVisitor v);'OnlySwordVisitor'extend'' Visitor'를 가질 필요가 없습니다. 단순히 WeaponVisitor를 사용할 수 있습니다, 맞습니까? –

+0

예, 물론입니다. 'SwordVisitor'는 검을 사용하는 방문자의 예입니다. 또한'AbstractWeapon이 Weapon을 구현하는 추상 클래스 '를 던지면 모든 구체적인 무기가 그 클래스를 서브 클래스 화하면 그 중 하나에서'accept' 만 구현하면됩니다 –

-1

당신은 당신이 명시 적 다운 캐스트없이 작동 방문자 패턴을 사용할 수 있습니다, 당신은 클래스의 고정 세트를 가지고 있기 때문에 호출 한 다음 각각의 방법

((Sword) weaponInventory.get(0)).wipeBloodfromSword(); 
+0

하지만 캐스팅하려면 먼저 유형 검사를해야합니다 ('instanceof '또는'getClass()'). 검이 인벤토리의 첫 번째 아이템이라는 보장은 없습니다. –