接口,类和代码气味

时间:2017-05-06 12:59:07

标签: java class interface

假设我有以下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);
}

和实施:

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

    }
}

在Effective Java中,其中一章建议我应该通过interface声明我的课程。我理解这些优点,但如果我有多个interface怎么办?

在我的主要方法中,我声明它是这样的:

ReloadableWeapon chargeGun = new ReloadableWeapon("ChargeGun",10);

并像这样使用它:

public static void reloadGameWeapon(Reloadable reload){
        reload.replenish(10);
}

public static void attackGameWeapon(Weapon toAttackwith){
        toAttackwith.attack();
}

如果我通过interface声明它,我显然只会获得特定接口提供的方法。我可以创建另一个名为ReloadedableWeapon的interface但是会​​放置哪些方法?我声明使用我的ReloadableWeapon糟糕的做法或代码味道是怎样的?

2 个答案:

答案 0 :(得分:1)

您可以创建一个扩展WeaponReloadable的接口。

public interface WeaponReloadable extends Weapon,Reloadable {
   ...
}

有了这个实现:

public final class MyWeaponReloadable implements  WeaponReloadable  {
   ...
}

通过这种方式,您可以创建使用MyReloadableWeapon接口声明的ReloadableWeapon实例,并将其传递给包含ReloadableWeapon参数的方法:

WeaponReloadable weaponReloadable = new MyWeaponReloadable();
reloadGameWeapon(weaponReloadable);
attackGameWeapon(weaponReloadable);

答案 1 :(得分:0)

您可以使用泛型来获取类型交集:

 public static <W extends Weapon & Reloadable> doSomething(W weapon){
     weapon.replenish(10);
     weapon.attack();
 }

通常,创建“交叉点界面”

更容易
interface ReloadableWeapon extends Weapon, Reloadable {}

但是泛型方法甚至适用于您无法修改其类型层次结构的类以包含该新接口(即第三方代码)。