簡體   English   中英

從父類中調用父方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM