不要从超类构造函数中调用子类方法 [英] Don’t call subclass methods from a superclass constructor
问题描述
考虑以下代码
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package example0;
/**
*
* @author yccheok
*/
public class Main {
static class A {
private final String var;
public A() {
var = getVar();
// Null Pointer Exception.
System.out.println("var string length is " + var.length());
}
public String getVar() {
return "String from A";
}
}
static class B extends A {
private final String bString;
// Before B ever constructed, A constructor will be called.
// A is invoking a overriden getVar, which is trying to return
// an initialized bString.
public B() {
bString = "String from B";
}
@Override
public String getVar() {
return bString;
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
B b = new B();
}
}
目前,在我看来,那里有两种方法可以避免这种问题。
Currently, in my mind, there are two ways to avoid such problem.
要么是A级的最后一堂课。
Either making class A final class.
static final class A {
private final String var;
public A() {
var = getVar();
// Null Pointer Exception.
System.out.println("var string length is " + var.length());
}
public String getVar() {
return "String from A";
}
}
或
使getVar方法最终
Making getVar method final
static class A {
private final String var;
public A() {
var = getVar();
// Null Pointer Exception.
System.out.println("var string length is " + var.length());
}
public final String getVar() {
return "String from A";
}
}
作者试图提出防范上述问题的方法。但是,解决方案似乎很麻烦,因为有一些规则要遵循。
The author trying to suggest ways to prevent the above problem. However, the solution seems cumbersome as there are some rules to be followed.
http://benpryor.com/blog/2008/01/02/dont-call-subclass-methods-from -a-superclass-constructor /
除了最终和作者建议的方式之外,还有更多方法可以防止上述问题(不要调用子类)来自超类构造函数的方法)发生了?
Beside making final and the author suggested way, is there more ways to prevent the above problem (Don’t call subclass methods from a superclass constructor) from happen?
推荐答案
使getVar方法最终成为
这绝对是你需要做的。
This is definitely what you need to do.
如果您正在转发初始化对象的方法的功能,则不应让子类破坏该方法。
If you're relaying on the functionality of a method to initialize an object, you shouldn't let subclasses broke that method.
回答你的问题其他方法来阻止它是让 getVar
私有 A
。
Answering your question, other way to prevent it is to make getVar
private in A
.
查看代码的简化版本:
// A.java
class A {
private final String var;
public A(){
var = getVar();
var.length();
}
private String getVar(){
return "This is the value";
}
}
class B extends A {
private final String other;
public B(){
other = "Other string";
}
public String getVar(){
return other;
}
}
class Main{
public static void main( String [] args ) {
new B();
}
}
BTW,你为什么把这些作为静态嵌套类,只是为了制造混乱?
BTW, why did you put those as static nested classes, just to create confusion?
这篇关于不要从超类构造函数中调用子类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!