在Java中,为什么我不能在父类中声明一个final成员(不初始化它)并在子类中设置它的值? 我该如何解决?
在 Java 程序中,我有多个从父类(抽象的)继承的子类。 我想表达的是,每个孩子都应该有一个仅设置一次的成员(我计划在构造函数中这样做)。 我的计划是编写代码。 像这样:
public abstract class Parent {
protected final String birthmark;
}
public class Child extends Parent {
public Child(String s) {
this.birthmark = s;
}
}
然而,这似乎并不能取悦Java诸神。 在父类中,我收到消息:birthmark
“可能尚未初始化”,在子类中,我收到“无法访问最终字段birthmark
”。
那么 Java 的方式是什么呢? 我缺少什么?
In a Java program, I have multiple subclasses inheriting from a parent (which is abstract). I wanted to express that every child should have a member that is set once only (which I was planning to do from the constructor). My plan was to code s.th. like this:
public abstract class Parent {
protected final String birthmark;
}
public class Child extends Parent {
public Child(String s) {
this.birthmark = s;
}
}
However, this seems to not please the Java gods. In the parent class, I get the message that birthmark
"might not have been initialized", in the child class I get "The final field birthmark
cannot be accessed".
So what's the Java way for this? What am I missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
你不能这样做,因为在比较父类时,编译器无法确定子类是否会初始化它。 您必须在父级的构造函数中初始化它,并让子级调用父级的构造函数:
You can't do it because while comparing the parent class, the compiler can't be sure that the subclass will initialize it. You'll have to initialize it in the parent's constructor, and have the child call the parent's constructor:
将其传递给父构造函数:
Pass it to the parent constructor:
另一种 Java 风格的方法可能是让父类定义一个抽象的“getter”,并让子类实现它。 在这种情况下,这不是一个好方法,但在某些情况下,它可能正是您想要的。
Another Java-ish way to do this is probably to have the parent class to define an abstract "getter", and have the children implement it. It's not a great way to do it in this case, but it in some cases it can be exactly what you want.
我会这样做:
final 意味着每个实例可以初始化该变量一次。 编译器无法确保每个子类都会提供对birthmark的赋值,因此它强制赋值在父类的构造函数中发生。
我添加了对 null 的检查,只是为了表明您还可以获得能够在一个位置而不是每个构造函数检查参数的好处。
I would do it like this:
final means that the variable can be initialized once per instance. The compiler isn't able to make sure that every subclass will provide the assignment to birthmark so it forces the assignment to happen in the constructor of the parent class.
I added the checking for null just to show that you also get the benefit of being able to check the arguments in one place rather than each cosntructor.
为什么不将初始化委托给方法。 然后重写父类中的方法。
这应该允许自定义初始化。
Why not delegate initialization to a method. Then override the method in the parent class.
This should allow custom initialization.
是的,最终成员将被分配到声明它们的类中。 您需要向 Parent 添加一个带有 String 参数的构造函数。
Yes, the final members are to be assigned in the class in which they are declared. You need to add a constructor with a String argument to Parent.
在超类中声明由子类调用的构造函数。
您必须在超类中设置该字段以确保其已初始化,否则编译器无法确保该字段已初始化。
Declare a constructor in the superclass that's called by the subclass.
You must set the field in the superclass to make sure it's initialized, or the compiler can't be sure the field is initialized.
您可能希望有一个 Parent(Stringbirthmark) 构造函数,以便确保在 Parent 类中 Final 始终被初始化。 然后你可以从 Child() 构造函数中调用 super(birthmark) 。
You probably want to have a Parent(String birthmark) constructor so that you can ensure in your Parent class that final is always initialized. Then you can call super(birthmark) from your Child() constructor.