[英]Calling parent method from within the parent class
這是我的代碼的摘錄
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
單獨創建CwDB
還有其他簡潔的解決方案,然后將它傳遞給IntelliCwDB
的構造函數只是為了重寫LinkedList<Entry>
dict數據庫嗎?
您遇到了一個不應該從構造函數中調用虛方法的原因之一 。 有關此內容的更多詳細信息,請參閱Effective Java 2nd Edition ,Item 17: Design and document for inheritance或禁止它 。
解決問題的最簡單方法是將基類方法拆分為非虛擬( final
和/或private
)方法,另一種方法是在基類實現中調用前者。
@aioobe更快地為此提供了一個例子:-)
你可以像這樣解決它:
創建CwDB.add
的私有(或最終)版本,我們稱之為privateAdd
。
讓CwDB
的舊add
方法調用此方法。
每當你想確定使用了CwDB
-version of add
,你只需要調用privateAdd
。
示例代碼
public class CwDB {
// ...
public void add(String word, String clue) {
privateAdd(word, clue);
}
private void privateAdd(String word, String clue) {
System.out.println("cwdb");
dict.add(new Entry(word, clue));
}
protected void createDB(String filename) {
// ...
// "Calling parent method from within the parent class" :-)
this.privateAdd(f.readLine(), f.readLine());
// ...
}
// ...
}
正如@PéterTörök正確指出的那樣:你永遠不應該在構造函數中直接或間接地調用虛方法。 原因很簡單:子類將在其超類(及其自身)正確初始化之前運行代碼。 (無論它是否適用於這個特定的例子,都可以說明理由。)
我將add
方法移動到addInternal
中的addInternal,並創建一個調用addInternal
的新add
。 然后在createDB
方法中,調用addInternal
以獲取正確的方法。 例如。
class CwDB {
..
private void addInternal(String word, String clue) {
..
}
public void add(String word, String clue) {
addInternal(word, clue);
}
public void createDB(String filename) {
..
addInternal(w, c);
..
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.