[英]Java- Using a constant in an abstract class that needs to be used by subclasses as well
[英]force subclasses to include constant in abstract java class
我有一个抽象类,我希望所有子类都根据实现定义一个常量——它主要是关于类实现的元数据。
在超类中:
protected static final String OBJECT_NAME;
protected static final String OBJECT_DEF;
然后在子类中:
protected static final String OBJECT_NAME = "awesome class";
protected static final String OBJECT_DEF = "an awesome class that is also great";
有没有办法强制类的实现声明一个常量?
您可以强制子类定义一个方法,该方法可以是该类的常量。
protected abstract String objectName();
protected abstract String objectDef();
注意:如果您有子类的子类,它们可能会“忘记”覆盖这些方法。
也可以选择一个接口,因为您没有超类的合理默认值:
interface HasObjectNameAndDef {
public String getObjectName();
public String getObjectDef();
}
然后让您的实际类实现接口。 作为奖励,您将获得更灵活的测试。
这是另一种方法。 我喜欢它,因为它很严格,让我们可以将大部分代码(包括 getter)放入父类中,使其子类保持整洁。
abstract class Parent {
private final int age;
private final String name;
Parent(int age, String name) {
this.age = age;
this.name = name;
}
int getAge() {
return age;
}
}
class Child extends Parent {
Child() {
super(18, "John");
// any other Child specific constructor logic
}
}
class Main {
public static void main(String[] args) {
var child = new Child();
System.out.println(child.getAge()); // Will print 18
}
}
注意: Child
不继承Parent
的构造函数,因此在初始化Child
时没有意外使用 wearg 构造函数的危险。
不,你不能。
你甚至不能在你的抽象超类中声明常量而不给它们分配具体的值。 在其他情况下,您将收到错误消息。 您应该在它们的声明期间或在类构造函数中初始化 final 字段。
您可以声明抽象方法来初始化您的变量(但这会更加混淆)。 像这样:
protected String OBJECT_NAME = getObjectNameValue();
public abstract String getObjectNameValue();
但在这种情况下,您的变量和方法不应该是静态的。 因为您不能将静态方法定义为抽象方法( 请看这里的解释)。
或者您可以直接使用方法而不是 Peter Lawrey 提出的变量,这将更具可读性。
这不会那样工作。 我将这些定义为抽象函数:
protected abstract String objectName();
protected abstract String objectDef();
在子类中:
private static final String OBJECT_NAME = "awesome class";
private static final String OBJECT_DEF = "bla";
protected String objectName(){
return OBJECT_NAME;
}
protected String objectDef(){
return OBJECT_DEF;
}
这些方法不是static
,但我认为这是最接近你想要的。
我知道你在说什么。
例如,我想要一个接口(我称之为 ExecutableList)有一个名为USER_FRIENDLY_NAME
字符串字段
public interface ExecutableList<T extends ExecutableList<T,E>,E> //This is type parameter
extends List<E>, //self referencing. Trust
Comparable<E>, //me, it has its uses.
{
/** This would declare a constant but leave it to sub-interfaces/classes to define it. */
abstract String USER_FRIENDLY_NAME;
//Define the rest of your interface
}
不幸的是,这在 Java 中是不可能的。 当您在 Java 接口中声明一个字段时,它意味着修饰符public
、 static
和final
。 Java 编程语言的未来更改可能允许添加abstract
,从而使隐含修饰符public abstract static final String USER_FRIENDLY_NAME;
但是,虽然您可以为此明确定义规则,但使用abstract
这个词会令人困惑,因为abstract
和final
通常被理解为定义相反的含义。
我交叉手指,Java 的未来版本将实现这一点。 我听说将在 Java 9 中添加私有接口方法(用于在默认方法之间使用),但还没有关于该语言添加的消息。 我敢肯定,首先要考虑许多向后兼容性问题。 如果 Oracle 的任何人读到了这篇文章,请让我们在接口中声明常量并让继承类/接口定义它们!!!
与此同时,你唯一的选择是定义一个String getUserFriendlyName();
接口或抽象类中的方法。 不那么优雅,也许也不那么高效,但目前您别无选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.