简体   繁体   中英

How to Check if a class extends another

I have seen variants of this question but none of them really address my problem.

Lets say I am building an army with classes. At the top of my Inheritance structure I have an abstract " Unit " class. Then an abstract " Flying ", " Ground " and " Building " class that extends unit. Then a concrete " Helicopter " and " Jet " class that extends Flying. As well as a concrete " Soldier " and " Tank " class that extends Ground. and finally a " HQ " and " Supply " that extends building.

The following is a method under the " Soldier " Class:

public void attack(Unit enemy){
if(enemy.getSuperclass().equals(Flying)){
    System.out.print("Soldiers cant attack flying units");
}
else{
    //Code to attack enemy here
}

I want enemy to be any form of unit. This is because a soldier should be able to attack both buildings and other ground units, However I don't want the Soldiers to be able to attack flying objects.

The obvious problem is that because I declared enemy as a Unit , it doesn't know which subclass it belongs to and therefore is trying to find a SuperClass for Unit which doesn't exist.

I'm sure I could have a getter for every unit which has manually set what type of unit it is... but that is more work and doesn't seem efficient.

Change

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

to

if(enemy instanceof Flying){

That will check if enemy is an instance of any of the classes that derive from Flying , rather than checking specifically for the Flying class (which we know enemy won't be, as Flying is abstract).

instanceof is quite handy, but whenever I use it (and I sometimes do), I step back and look at my structure in hopes that I can find some way to refactor to avoid it (perhaps things that can be attacked by soldiers have some common characteristic and could implement an abstract Unit sub-class — GroundBased or something — which you could use for the argument instead of Unit ). You may not be able to in this case, but it's worth double-checking.

Try using instanceof operator.

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

You can use instanceof for this. This also works ie for interfaces.

Take also care that the variable may not be null when using instanceof.

class B extends 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");
    }
   }
if (enemy instanceof Flying)
   ...

你试过了吗:

if (enemy instanceof Flying)

I think you are looking for instanceof operator .

The instanceof operator compares an object to a specified type. You can use it to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.

So you can update you function like following:

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

尝试if(enemy instanceof Flying) {}

This is a design smell. The fundamental requirement is a job for the Visitor pattern but you should also be looking to use polymorphism better than this before you even get to the Visitor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM