假设我有两个课。
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聊天服务器上询问了这个问题,但我仍然感到困惑。
答案 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");
}
}