The use of instanceof
or getClass()
is largely considered code smell. Is using a variable to indicate the type of object you're using also considered code smell?
Suppose if I had an enum
called WeaponType
:
public enum WeaponType { ReloadableWeapon // -- imagine more weapon types }
and Weapon
class:
public abstract class Weapon { private WeaponType wt; public Weapon(WeaponType wt) { this.wt = wt; } } public ReloadableWeapon extends Weapon{ public ReloadableWeapon() super(WeaponType.ReloadableWeapon); { } }
In this example, I'm using an enum
to determine the type of weapon, essentially, I'm doing with the enum
what I can do with instanceof
or getClass()
.
I can check if the weapon is a certain type and proceed, for example, suppose in my game I allow the player to view their weapons based on type in a quick view while under attack.
I can collect all the weapons like so:
List<Weapon> reloadableWeapons = new ArrayList<Weapon>(); for (Weapon weapon : inventory){ if weapon.istypeof(WeaponType.ReloadableWeapon){ reloadableWeapons.add(weapon); } } // code to render reloadableWeapons to UI
Of course this doesn't have to be an enum
, it could be any variable, String
or int
but it's purpose is to indicate what type of object you have.
Notice, I'm not using the enum
to check the Weapon
and downcast, or controlling behavior. I simply want to single out weapons of a specific type and perform an action, in this case, display in a UI.
ReloadableWeapon
should not be a type at all. Your baseWeapon
class should have anisReloadable
flag, default tofalse
... Likewise for every attribute you'd want to filter weapons on... I won't actually make that argument. It's an argument I would flesh out pretty thoroughly if this were my design though.Weapon
should worry if it's reloadable or not. What about other types? This meansWeapon
is going to change every time i add a new type?