How to Check if a class extends another

10,474

Solution 1

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.

Solution 2

You can use instanceof for this. This also works i.e. 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");
    }
   }

Solution 3

Try using instanceof operator.

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

Solution 4

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

Solution 5

if (enemy instanceof Flying)
   ...
Share:
10,474
KroniK907
Author by

KroniK907

Updated on July 28, 2022

Comments

  • KroniK907
    KroniK907 over 1 year

    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.

  • Devolus
    Devolus about 11 years
    Rethinking the class design is a good advice. A good way might also be to use an interface and implement the common parts in a subclass Unit. With an interface you don't have to worry that a class is derived from a particular implementation of another class but you still can make sure that the bevhiour is the same.
  • KroniK907
    KroniK907 about 11 years
    yes but an interface wont let me create cookie cutter methods to apply to the concrete classes below it. I would have to re-create the method for every unit. Unless I don't understand interfaces correctly.