如何检查一个类是否继承自另一个类

8
我看到这个问题的变种,但是它们都没有真正解决我的问题。
假设我正在使用类来构建一个军队。 在继承结构的顶部,我有一个抽象的 "Unit" 类。 然后是一个抽象的 "Flying"、"Ground" 和 "Building" 类,它们扩展了 Unit。 接着是一个具体的 "Helicopter" 和 "Jet" 类,它们扩展了 Flying。 还有一个具体的 "Soldier" 和 "Tank" 类,它们扩展了 Ground。 最后是一个扩展 Building 的 "HQ" 和 "Supply"。
以下是“Soldier”类下的一个方法:
public void attack(Unit enemy){
if(enemy.getSuperclass().equals(Flying)){
    System.out.print("Soldiers cant attack flying units");
}
else{
    //Code to attack enemy here
}

我希望“敌人”可以是任何一种单位形式。这是因为士兵应该能够攻击建筑和其他地面单位,但我不希望士兵能够攻击飞行物体。
显然的问题是,因为我将“敌人”声明为一个“单位”,它不知道属于哪个子类,因此试图找到不存在的“单位”超类。
我相信我可以为每个单位设置getter手动设置其类型...但那样更费力,也不够高效。

2
哇,同一10秒时间片内发布了5个等效答案! - Bruno Reis
2
你也可以使用接口,因为类继承可能过于严格以至于无法模拟所有情况。但首先尝试继承是可以的。 - Joop Eggen
1
instanceof 的惊奇! - AllTooSir
我建议在飞行、地面和建筑类中实现攻击方法,并重载每种可能的攻击方式,例如在飞行类中:attack(Flying enemy) attack(Ground enemy) attack(Building enemy) - Joan
7个回答

16

改变

if(enemy.getSuperclass().equals(Flying)){

if(enemy instanceof Flying){

那会检查enemy是否是任何从Flying派生的类的实例,而不是特别检查Flying类(我们知道Flying是抽象的,所以enemy不可能是Flying类)。

instanceof非常方便,但每当我使用它时(有时候会这样),我会回过头来看我的结构,希望找到一些重构的方法来避免使用它(也许可以攻击士兵的东西有一些共同的特征,并且可以实现一个抽象的Unit子类-如GroundBased或类似的-你可以用它来代替参数中的Unit)。在这种情况下,您可能无法这样做,但值得仔细检查。


重新思考类的设计是一个好建议。一个好的方法也许是使用接口并在子类Unit中实现共同部分。使用接口,您不必担心一个类是从另一个类的特定实现派生的,但仍然可以确保行为相同。 - Devolus
是的,但接口不会让我创建模板方法来应用于其下面的具体类。我必须为每个单元重新创建该方法。除非我没有正确理解接口。 - KroniK907

2

你可以使用instanceof来实现这个功能。这也适用于接口。

在使用instanceof时,请注意变量可能不为空。

class 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");
    }
   }

2

尝试使用 instanceof 运算符。

    if(enemy instanceof Flying){
        System.out.print("Soldiers cant attack flying units");
    }
    else{
        attack(enemy);
    }

1
if (enemy instanceof Flying)
   ...

1

你尝试过吗:

if (enemy instanceof Flying)

1
尝试使用 if(enemy instanceof Flying) {}

0

这是一种设计上的问题。基本要求是使用访问者模式,但在使用访问者模式之前,您应该更好地运用多态性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接