我已经看到了这个问题的变体,但它们都没有真正解决我的问题。
让我们说我正在建立一个有班级的军队。在我的继承结构的顶部,我有一个抽象的“单元”类。然后是一个抽象的“飞行”,“地面”和“构建”类,它扩展了单位。然后是一个具体的“ Helicopter ”和“ Jet ”类,它扩展了Flying。除了一个具体的“士兵”和“坦克”这个扩展Ground的课程。最后是“ HQ ”和“供应”,这些都延伸了建筑。
以下是“士兵”类下的方法:
public void attack(Unit enemy){
if(enemy.getSuperclass().equals(Flying)){
System.out.print("Soldiers cant attack flying units");
}
else{
//Code to attack enemy here
}
我希望敌人成为任何形式的单位。这是因为士兵应该能够攻击建筑物和其他地面单位,但我不希望士兵能够攻击飞行物体。
显而易见的问题是,因为我将敌人声明为单位,所以它不知道它属于哪个子类,因此正在尝试为单位找到一个SuperClass哪个不存在。
我确信我可以为每个已经手动设置它是什么类型的单位的单位获得一个吸气剂......但这是更多的工作而且看起来效率不高。
答案 0 :(得分:12)
更改
if(enemy.getSuperclass().equals(Flying)){
到
if(enemy instanceof Flying){
这将检查enemy
是否是从Flying
派生的任何类的实例,而不是检查具体的Flying
类(其中我们知道enemy
不会,因为Flying
是抽象的。)
instanceof
非常方便,但每当我使用它时(我有时会这样做),我退后一步看看我的结构,希望我能找到一些方法来重构以避免它(也许是可以的东西)被士兵攻击有一些共同的特征,可以实现一个抽象的Unit
子类 - GroundBased
或其他东西 - 你可以用它来代替Unit
。在这种情况下你可能无法做到,但值得仔细检查。
答案 1 :(得分:2)
尝试使用instanceof运算符。
if(enemy instanceof Flying){
System.out.print("Soldiers cant attack flying units");
}
else{
attack(enemy);
}
答案 2 :(得分:2)
您可以使用instanceof。这也适用于接口。
使用instanceof时,请注意变量可能不为null。
B类延伸A
public class test
{
public static void main(String[] args)
{
A a = new B();
B b = new B();
if(a instanceof A)
System.out.println("B derived from A");
if(b instanceof A)
System.out.println("B derived from A");
}
}
答案 3 :(得分:1)
if (enemy instanceof Flying)
...
答案 4 :(得分:1)
你有没有尝试过:
if (enemy instanceof Flying)
答案 5 :(得分:1)
我认为您正在寻找instanceof
operator。
instanceof
运算符将对象与指定类型进行比较。您可以使用它来测试对象是否是类的实例,子类的实例或实现特定接口的类的实例。
因此,您可以更新以下功能:
if(enemy instanceof Flying){
System.out.print("Soldiers cant attack flying units");
}
else{
attack(enemy);
}
答案 6 :(得分:1)
尝试if(enemy instanceof Flying) {}
答案 7 :(得分:0)
这是一种设计气味。基本要求是Visitor pattern的工作,但在你到访问者之前,你也应该更好地使用多态性。