2013-04-10 4 views
2

Item의 하위 클래스 인 Weapon 클래스의 메서드를 호출하려고합니다. 필드에서 볼 수 있듯이 객체의 객체로 currentWeapon 객체를 선언했으며 setCurrentWeapon 메서드에서는 getClass() 메서드를 사용하여 Item이 실제로 하위 클래스의 무기인지 확인합니다.클래스의 하위 클래스에서 객체에 대한 메서드 호출

Weapon 클래스에서 내 Item 객체 (실제로는 Weapon 클래스 임)의 메서드를 성공적으로 호출 할 수있는 방법이 있습니까?

backpackItem 개체를 포함하는 해시 맵입니다. 필드에 currentWeaponWeapon으로 설정하면 Weapon 개체가 backpack에 추가되지 않습니다.

컴파일에 실패있어서 는 (기호를 찾을 수 없습니다 - 방법 getMinDamage())

public int attack(Imperial currentEnemy) { 
    int damage = Utils.random(currentWeapon.getMinDamage(), currentWeapon.getMaxDamage()+1); 
    currentEnemy.changeHealth(-damage); 
    return damage; 
} 

필드 :

public boolean setCurrentWeapon(String itemToEquip) { 
    if(useItem(itemToEquip) == true) { 
     currentWeapon = backpack.get(itemToEquip.toLowerCase()); 
     if(currentWeapon.getClass() == Weapon.class) { 
      System.out.println(getNick() + " has equipped " + currentWeapon.getName() + " as current weapon"); 
      equipped = true; 
      return true; 
     } 
     else { 
      System.out.println(itemToEquip + " is not a weapon"); 
      currentWeapon = null; 
      return false; 
     } 
    } 
    else System.out.println(itemToEquip + " is not owned by " + getNick()); 
    return false; 
} 
: currentWeapon을 설정하는

private Item currentWeapon; 

방법

이 질문이 너무 혼란스럽지 않기를 바래요, 명확하게하는 방법에 대한 조언을주십시오. 이것이 문제인 경우

+2

당신의 필드는 'currentWeapon'이라고 불리지 만 Weapon이 아닌 Item 타입을 주어야합니다. 무엇이든 당신의 보트를 떠 다닙니 다. :) – vptheron

+0

아마도 추상적 인 방법을 사용하면 ... 질문이 매우 명확하지 않습니다 ... – DGomez

답변

4

귀하의 문제는 당신이

currentWeapon.getMinDamage() 

currentWeapon를 호출 할 때 Item을 입력 가지고 있다는 것입니다. 그것은 런타임 유형이 Weapon이지만 잘못된 유형이라는 컴파일 타임 오류가 발생합니다.

((Weapon)currentWeapon).getMinDamage() 
+0

고맙습니다 제 질문에 대한 탁월한 답을 얻으 려합니다. 매우 유익하고 솔루션은 완벽하게 작동했습니다. – user1736049

1

instanceof을 사용하여 어떤 것이 클래스의 인스턴스인지 여부를 확인할 수 있습니다. 이 경우 다음을 사용할 수 있습니다.

Weapon a; Item b; 
if(a instanceof Weapon) returns true 
if(b instanceof Weapon) returns false 

그런 다음 간단히 캐스팅 할 수 있습니다.

instanceof은 첫 번째 인수의 개체가 두 번째 인수의 형식인지 여부를 확인하므로 두 번째 인수에 형식을 안전하게 캐스팅 할 수 있습니다. 따라서 아이템이 무기 인 경우 무기로 구체적으로 인스턴스화해야합니다.

따라서 Weapon instanceof Item도 마찬가지입니다.

코드에 오류가있는 이유는 항목에 무기 전용 기능을 호출한다는 것입니다. 아이템을 무기에 던지거나 던지기 위해 먼저 체크해야합니다.

2

당신은 확인할 수 있습니다 : 당신은 필드 타입 Item의 유지하려는 경우, 당신은 당신이 정말 유형 Weapon이 될 것으로 기대하는 컴파일러에게, 그 메소드를 호출하기 전에 Weapon에 캐스팅해야합니다 instanceof WeaponItem의 유형을 입력 한 다음 ItemWeapon으로 전송하십시오.

Backpack에 대한 더 나은 디자인은 다른 유형의 인벤토리 모음을 다른 래핑하는 클래스로 만드는 것일 수 있습니다. 예를 들어, 당신은 할 수 : 항목은 오른쪽 컬렉션에 추가되도록

class Backpack { 
    List<Weapon> weapons; 
    List<Armor> armory; 
    List<Provision> provisions; 
    ... 
} 

는 그런 다음 add 방법을 과부하.

이렇게하면 배낭의 모든 항목을 일반 가방 Item (예 : 배낭 총중량을 가져와야하는 경우)으로 처리해야하는 경우 모든 컬렉션을 반복 할 수 있습니다. 편의를 위해 여전히 다른 유형의 Item을 분리하여 보관하십시오.

+0

이것은 좋은 생각입니다. 고맙습니다! – user1736049

관련 문제