从父类中调用父方法

时间:2010-10-20 09:05:16

标签: java methods nested parent

以下是我的代码摘录

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数据库吗?

3 个答案:

答案 0 :(得分:3)

您遇到了不应该从构造函数中调用虚方法的原因之一。有关详细信息,请参阅Effective Java 2nd Edition,第17项:设计和文档以继承或禁止它

解决问题的最简单方法是将基类方法拆分为非虚拟(final和/或private)方法,另一种方法是将虚拟方法调用基类实现。

@aioobe更快地为此提供了一个例子: - )

答案 1 :(得分:2)

你可以这样解决:

  • 创建CwDB.add的私有(或最终)版本,我们称之为privateAdd

  • add中的旧CwDB方法改为调用此方法。

  • 每当您想确保使用CwDB版本的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正确指出的那样:你永远不应该在构造函数中直接或间接地调用虚方法。原因很简单:子类将在其超类(及其自身)正确初始化之前运行代码。 (不管它是否适用于这个特定的例子,都可以说明理由。)

答案 2 :(得分:1)

我会将add方法移至CwDB中的addInternal,然后创建一个调用add的新addInternal。然后在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);
      ..
   }
}