Suppose I have the following interfaces
:
public interface GameObject {
void viewDetails();
}
public interface Weapon extends GameObject {
void attack();
}
//A weapon is not the only item reloadable. A container could be refilled.
public interface Reloadable extends GameObject {
void replenish (final int amount);
}
and Implementation:
public final class ReloadableWeapon implements Reloadable, Weapon {
private String weaponName;
private int numberofbullets;
public ReloadableWeapon(String name, int bullets){
this.weaponName = name;
this.numberofbullets = bullets;
}
@Override
public void replenish(final int amount) {
this.numberofbullets = amount;
}
@Override
public void attack() {
System.out.println(this.weaponName + " fired");
this.numberofbullets--;
System.out.println("Shots Left: " + this.numberofbullets);
}
@Override
public void viewDetails() {
System.out.println(this.weaponName);
}
}
In Effective Java, one of the chapters suggests that I should declare my class by the interface
. I understand the advantages, but what if I have more than one interface
?
In my main method I declare it like so:
ReloadableWeapon chargeGun = new ReloadableWeapon("ChargeGun",10);
and use it like this:
public static void reloadGameWeapon(Reloadable reload){
reload.replenish(10);
}
public static void attackGameWeapon(Weapon toAttackwith){
toAttackwith.attack();
}
If I declare it by interface
, I'll obviously only get the methods that specific interface provides. I could create another interface
called ReloadedableWeapon but what methods would be placed there? Is how I declared and used my ReloadableWeapon bad practice or code smell?
You could use generics to get a type intersection:
Usually, it is easier to just create an "intersection interface"
but the generics approach works even with classes whose type hierarchy you cannot modify to include that new interface (i.e. third-party code).
You could create a interface that extends both
Weapon
andReloadable
.And having this implementation :
In this way you could create an instance of
MyReloadableWeapon
declared with theReloadableWeapon
interface and pass it in methods withReloadable
orWeapon
parameters :