Calling the parent method from the parent class

Here is an excerpt from my code

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"); } } 

And 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(); } } } 

In the main() I create a new IntelliCwDB object that starts the execution of createDB() .

The problem is that I want CwDB.createDB() use the native CwDB.add() method, and not the one that was from IntelliCwDB . Is there another neat solution than creating CwDB separately and then passing it to the IntelliCwDB constructor to rewrite the LinkedList<Entry> dict database?

+4
source share
3 answers

You have one of the reasons why you cannot call virtual methods from the constructor . For more information, see Effective Java 2nd Edition, clause 17: “Design and document for inheritance” or “deny” it.

The simplest solution to your problem would be to break the base class method into not virtual ( final and / or private ) one, but another virtual method that calls the first in the base class implementation.

@aioobe provided an example faster :-)

+3
source

You can solve it as follows:

  • Create a private (or final) version of CwDB.add , call it privateAdd .

  • Let the old add method in CwDB call this method.

  • If you want to make sure that the CwDB version of add , you simply call privateAdd .

Code example

 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()); // ... } // ... } 

As @ Péter Török correctly points out: you should never call a virtual method (directly or indirectly) from within the constructor. The reason is simple: the subclass will run the code before its superclass (and itself) is properly initialized. (Regardless of whether this applies in this particular example, this may be the reason.)

+2
source

I would move the add method to addInternal in CwDB and create a new add that calls addInternal . Then, in the createDB method createDB call addInternal to get the correct method. For instance.

 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); .. } } 
+1
source

All Articles