java从父类中调用父方法
以下是我的代码摘录
package dictionary;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.regex.*;
public class IntelliCwDB extends CwDB {
public IntelliCwDB(String filename) {
super(filename);
}
@Override
public void add(String word, String clue) {
System.out.println("inelli");
}
}
还有CwDB
package dictionary;
import java.util.LinkedList;
import java.io.*;
import java.util.Scanner;
public class CwDB {
protected LinkedList<Entry> dict;
public CwDB(String filename) {
dict = new LinkedList<Entry>();
createDB(filename);
}
public void add(String word, String clue) {
System.out.println("cwdb");
dict.add(new Entry(word, clue));
}
protected void createDB(String filename) {
try {
BufferedReader f = new BufferedReader(new FileReader(filename));
while (f.ready()) {
this.add(f.readLine(), f.readLine());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
在main()
部分中,我创建了一个新的IntelliCwDB
对象,它触发createDB()
的执行
问题是我希望CwDB.createDB()
使用它自己的CwDB.add()
方法,而不是IntelliCwDB
中的方法。除了分别创建CwDB
,然后将其传递到IntelliCwDB
的构造函数中,仅仅为了重写LinkedList<Entry>
dict数据库之外,还有其他简洁的解决方案吗
# 1 楼答案
你可以这样解决:
创建
CwDB.add
的私有(或最终)版本,让我们称之为privateAdd
让
CwDB
中的旧add
方法调用此方法每当您想确保使用
CwDB
版本的add
时,只需调用privateAdd
示例代码
正如@péter Török正确指出的那样:永远不要从构造函数中(直接或间接)调用虚方法。原因很简单:子类将在其超类(及其本身)正确初始化之前运行代码。(不过,它是否适用于这个特定的例子是有道理的。)
# 2 楼答案
您遇到了不应该从构造函数调用虚拟方法的原因之一。有关这方面的更多详细信息,请参见Effective Java 2nd Edition,第17项:继承的设计和文档,或者禁止它
解决问题的最简单方法是将基类方法拆分为一个非虚拟(
final
和/或private
)方法和另一个虚拟方法,后者在基类实现中调用前者@aioobe更快地提供了一个例子:-)
# 3 楼答案
我将把
add
方法移动到CwDB中的addInternal
,并创建一个新的add
调用addInternal
。然后在createDB
方法中,调用addInternal
以获得正确的方法。 例如