覆盖变量或强制使用?

时间:2009-10-07 13:22:20

标签: java interface variables

我想强制一个类从它实现的类中定义某个变量。 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一样吗?

3 个答案:

答案 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;
}