通过Java中的接口传递设置-可以吗?

时间:2019-03-22 23:11:01

标签: java java-8 interface

假设我有两个课。

public class Banana extends Fruit{    
    public Banana() {
        this.setTitle("Banana");
        this.setSize("Medium");
        this.setState("Rotten");
    }
}
public class Sausage extends Meat{    
    public Sausage() {
        this.setTitle("Sausage");
        this.setSize("Medium");
        this.setState("Rotten");
    }
}

是否有一种方法可以引入一个可以保存通用设置的接口(可能是默认方法)?两个原始扩展名都应保留。

我已经在接口和默认方法上搜索了大约一个小时,并在Java聊天服务器上询问了这个问题,但我仍然感到困惑。

4 个答案:

答案 0 :(得分:1)

您不能直接执行此操作。我认为您在这里基本要问的是多重继承,这个概念似乎给Java语言设计者带来了很多麻烦。您可以自己实现类似的东西。

假设您有一个界面Food

public interface Food {    
    void setTitle(String s);
    void setSize(String s);
    void setState(String s);
}

然后您可以执行以下操作:

public class BaseFood implements Food {  
    private String title;  
    private String size;  
    private String state;  
    // setters and getters...
}

然后这个:

public class Banana extends Fruit implements Food {    
    private BaseFood food = new Food();
    public Banana() {
        food.setTitle("Banana");
        food.setSize("Medium");
        food.setState("Rotten");
    }
}

为完整起见,这里是Sausage,与Banana基本相同:

public class Sausage extends Meat implements Food {    
    private BaseFood food = new Food();
    public Sausage() {
        food.setTitle("Kielbasa");
        food.setSize("Medium");
        food.setState("Tasty");
    }
}

这称为“委托”,在其中您将Java中某个接口的实现委派给另一个对象,仅声明它实现了一个通用接口,然后仅在实际实现该接口的私有实例上调用方法。基本上是手动多重继承。

我的IDE(NetBeans)可以为我完成大部分工作,这很常见。给定一个接口和一个实现该接口的私有实例成员,它将编写公开实现该接口所需的所有方法。它可以正常工作,但可以生成很多样板。我有些希望Java专家至少会为“多重继承问题”提供一种部分语言解决方案。

编辑:您说没有共同的基类,但是您这样说:

  

在这种情况下,您不能创建基类,因为它是具有单一继承的Java-并且Sausage和Banana都已经扩展了某些内容。除非我缺少任何东西,否则您可以看到...

如果可以更改继承,则可以创建一个通用基类:

class Food { ...
class Fruit extends Food {...
class Banana extends Fruit {...
class Meat extends Food {...
class Sausage extends Meat { ...

但是我的回答假设您出于任何原因都无法执行此操作。

答案 1 :(得分:0)

问题是:您想拥有什么样的财产?

您可以在接口中声明 public static final 字段,就像在任何类中一样:

public interface MyInterface {
    String PROPERTY = "MyProperty";
}

如果这还不够,您可能必须使用继承而不是接口,并在其中将通用属性存储在抽象对象中。

答案 2 :(得分:0)

接口用于定义一些常见的行为。如果需要通用的 state ,则应使用一个基类,如果不直接实例化它,也可以使其抽象。

答案 3 :(得分:0)

接口仅定义实现必须满足的协定,但通常不会公开任何实现细节。 (此处不考虑默认方法)

您的意思可能是一个abstract类或一个将这些公共属性继承为子类的公共超类。这些类可以保持具体状态。

/**
 * The contract for each food.
 * You can get its title, size and its state. Also, the state can be changed.
 */
public interface Food {
    String getTitle();
    String getSize();
    String getState();
    void setState(String state);
}

现在,一个abstract类可以定义常见行为:

public class AbstractFood implements Food {

    private String title;
    private String size;
    private String state;

    public AbstractFood(String title, String size, String state) {
        this.title = title;
        this.size = size;
        this.state = state;
    }

    @Override
    public String getTitle() {
        return null;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    @Override
    public String getSize() {
        return null;
    }

    public void setSize(String size) {
        this.size = size;
    }

    @Override
    public String getState() {
        return null;
    }

    @Override
    public void setState(String state) {
        this.state = state;
    }
}

这些类可以具有任意子类,例如Fruit

public class Fruit extends AbstractFood {

    public Fruit(String title, String size, String state) {
        super(title, size, state);
    }
}

定义一个类Banana,它是一个Fruit

public class Banana extends Fruit {

    public Banana(String size, String state) {
        super("Banana", size, state);
    }
}

回到Food界面的用户,您现在可以在所有类型的食物上应用常见行为,而无需了解任何实现细节。例如,您可以将所有香蕉的状态更改为烂:

for (Fruit fruit : fruits) {
    if (fruit.getTitle().equals("Banana")) {
        fruit.setState("Rotten");
    }
}