我想强制一个类从它实现的类中定义某个变量。 e.g。
class Fruit{
String name; // Cause each fruit has a name
}
//Apple wants to get an error if it does not use the name variable
class Apple implements Fruit {
String name = "Apple";
}
有办法吗?就像java.io.Serializable一样吗?
答案 0 :(得分:11)
我想,最简单的方法就是使用构造函数。
class Fruit{
private final String name;
public Fruit(String name){
if (/* name has an incorrect value, is null or whatever */)
throw new IllegalArgumentException("name");
this.name = name;
}
}
//Apple wants to get an error if it does not use the name variable
class Apple extends Fruit {
public Apple(){ super("Apple"); }
}
现在不可能创建一个Fruit
子类,它不会将名称传递给Fruit
构造函数。通过创建字段final
,您还可以获得额外的奖励,一旦字段设置为正确的值,子类不能在那里放置虚假的东西(除了使用反射等,但所有的投注都关闭)
编辑另外,正如更贴心的海报所指出的那样,你不是implement
课程,而是你extend
。对于接口(你做 implement
),你不能强制从方法中返回合理的值(不是以任何简单的方式 - 我想你可以使用AOP来检查返回值,并在返回虚假值时抛出IllegalStateException
。
答案 1 :(得分:3)
您无法在Java中覆盖变量。只需使用带有setter / getters的接口或gustafc的构造函数变体。这是一个快速的例子:
interface Fruit {
String getName();
void setName(String name);
}
class Apple implements Fruit {
private String myName="";
public void setName(String name) { myName=name;}
public String getName() { return myName;}
}
我个人赞成构造函数变体,所以事情不会变为null。
答案 2 :(得分:1)
子类构造函数中的第一个调用是对超类构造函数的调用(必需,如果需要,由编译器添加)。因此,当必须在子类构造函数中计算所需的值时,"构造函数策略"不可能。在这种情况下,可以使用以下策略:
在超类中声明一个abstracct方法,返回所需的值,例如:
protected abstract String getValue();
在超类中,只要您需要该值,请使用getValue()
方法。
在子类中将值存储为私有字段,例如:
private String value;
在子类中初始化/设置值(例如在构造函数中)并实现抽象方法(必需,类不编译,否则):
@Override
protected String getValue() {
return value;
}