Java 不使用'的类;t实现所有接口方法

Java 不使用'的类;t实现所有接口方法,java,oop,interface,Java,Oop,Interface,我问了一个关于如何构造代码的问题,假设一个对象可以以多种方式使用 我的武器等级是这样的: public interface Weapon { void attack(); } public class Ak12 extends AbstractWeapon{ public void attack(){ //TO IMPELEMENT } public void reloadBullet(Bullet bullets){ //to implement } publ

我问了一个关于如何构造代码的问题,假设一个对象可以以多种方式使用

我的武器等级是这样的:

public interface Weapon {
     void attack();
} 
 public class Ak12 extends  AbstractWeapon{
 public  void attack(){
  //TO IMPELEMENT
 }

public void reloadBullet(Bullet bullets){
  //to implement
}
public abstract boolean isReloadable(){
//To implement
}
} 
和一个可重复使用的接口:

public interface Reload {
     void Reload(Bullet bullets);
} 
Weapon ak12 =new Ak12();
有人建议我将我的重新加载方法与武器界面相结合,然而,并非所有武器都可以重新加载。根据用户的说法,我可以用布尔值检查武器是否可以重新加载,因此我的武器界面现在是:

public interface Weapon {
     void attack();
     boolean isReloadable();
     void Reload(Bullet bullets);
} 

如果武器不可重新加载,那么布尔值将返回false,方法reload将保留为空。这是否违反了应该实现接口的所有方法的原则?有没有替代方法?

您可以使用一个抽象类,并用一个空的主体声明方法,而实际上不需要由其他类初始化。

这是一个设计问题,使用您发布的方法最好抛出一个
如果有人在不可重新加载的武器上调用
reload()
,而不是将方法保留为空/未实现….

将重新加载移动到单独的接口中的想法允许您在定义类时根据需要混合和匹配接口。如果武器不可重新加载,请不要在建模该武器的类中实现
reloadable
接口

以下是一个例子:

class AK47 implements Weapon, Reloadable {
    public void attack() {
        System.out.println("rat-a-tat");
    }
    public void reload(Bullet bullets) {
        System.out.println("+30 rounds");
    }
}
class Chainsaw implements Weapon {
    public void attack() {
        System.out.println("Bzzzz");
    }
}

您可以使用
instanceof
操作符来测试
武器的实例是否可以
重新加载

您必须知道接口的契约。 武器攻击和重装

public interface Weapon {
 void attack();
 void reload(Bullet bullets);
} 
检查武器是否可重新加载不属于合同,但它只是执行重新加载方法的一种手段,这是一种公共行为,当我们谈论公共时,我们谈论的是一个母类

您需要有一个实现此接口的抽象类

public abstarct class AbstractWeapon implements Weapon {
 public abstract void attack();
 public void reload(Bullet bullets){
   if (isReloadable())
     reloadBullet(bullets);

 }
public abstract void reloadBullet(Bullet bullets);
public abstract boolean isReloadable();
} 
例如,您的类武器(ak12)继承了AbstractBearm,并且能够实现三种方法ReloadBillot和attack以及isReloadable,如下所示:

public interface Weapon {
     void attack();
} 
 public class Ak12 extends  AbstractWeapon{
 public  void attack(){
  //TO IMPELEMENT
 }

public void reloadBullet(Bullet bullets){
  //to implement
}
public abstract boolean isReloadable(){
//To implement
}
} 
最后,您可以通过界面引用ak12:

public interface Reload {
     void Reload(Bullet bullets);
} 
Weapon ak12 =new Ak12();

您的ak12攻击、重新加载并尊重您的可重新加载条件

我认为将重新加载定义为单独的界面更好,然后您可以设置重新加载工具动态

public abstract class AbstractWeapon implements Weapon{
    private Reload reload = EmptyReload.instance();  //default do nothing

    public Reload getReload() {
        return reload;
    }

    public void setReload(Reload reload) {
        this.reload = reload;
    }

    //add reload method 
    public void reLoad(Bullet bullets){
        reload.reload(bullets);
    }
}
EmptyReload是一个空对象,不执行任何操作:

public class EmptyReload implements Reload{

    private static EmptyReload emptyReload = new EmptyReload();

    private EmptyReload() {
    }

    public static EmptyReload instance(){
        return emptyReload;
    }

    @Override
    public void Reload(Bullet bullets) {
        //can not reload,do nothing
    }
}
然后你的枪械:

public class Gun extends AbstractWeapon{
    public Gun() {
        setReload(bullets -> System.out.println("reload bullets"));
    }

    @Override
    public void attack() {
        //impl
    }
}
或在需要时更改其重新加载机具:

Gun gun = new Gun();
gun.setReload(bullets -> System.out.println("switch reload interface"));

在我看来,最好实现一个类层次结构:一个抽象的类武器,它包含所有类型武器共有的属性和方法(例如
攻击()
),然后每个特定类型武器的一个类应该扩展它,因此类
reloadablebarm扩展了武器实现Reload
,并实现了
Reload()
方法。