Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 567
KroniK907 Avatar asked Apr 17 '13 08:04

KroniK907


2 Answers

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.

like image 79
T.J. Crowder Avatar answered Oct 17 '22 02:10

T.J. Crowder


Try using instanceof operator.

    if(enemy instanceof Flying){
        System.out.print("Soldiers cant attack flying units");
    }
    else{
        attack(enemy);
    }
like image 36
Averroes Avatar answered Oct 17 '22 01:10

Averroes