someone
someone

Reputation: 361

Can an inherited method call an overriding method instead of the original?

Imagine the following situation, where an inherited method that calls a method of the superclass must call a method of the child class instead:

// super.java

public class Processor {
   public void process(String path) {
      File file = new File(path);

      // some code
      // ...

      processFile(file);
   }
   protected void processFile(File file) {
      // some code
      // ...

      reportAction(file.name());
   }
   protected void reportAction(String path) {
      System.out.println("processing: " + path);
   }
}

// child.java

public class BatchProcessor extends Processor {
   public void process(String path) {
      File folder = new File(path);
      File[] contents = folder.listFiles();
      int i;

      // some code
      // ...

      for (i = 0; i < contents.length; i++) super.processFile(file);
   }
   protected void reportAction(String path) {
      System.out.println("batch processing: " + path);
   }
}

Obviously, the code presented above doesn't work as it should. The class BatchProcessor prints "processing: <file>" instead of "batch processing: <file>" as it calls the method from the superclass instead of the new one. Is there any way to overcome this obstacle?

Thanks in Advance! :D

Upvotes: 0

Views: 115

Answers (2)

kiruwka
kiruwka

Reputation: 9450

Try this :

Processor processor = new Processor();
processor.process("filePath"); // will print "processing: <file>"
// and 
Processor batchProcessor = new BatchProcessor();
batchProcessor.process("filePath"); // will print "batch processing: <file>"

this is how polymorphic methods work. I guess you are just not calling processor on subclass instance ?

edit Please run the following code for a quick proof for yourself:

class Parent {
    void test() {
        subTest();
    }

    void subTest() {
        System.out.println("subTest parent");
    }
}

class Child extends Parent {
    void subTest() {
        System.out.println("subTest Child");
    }
    public static void main(String... args) {
        new Child().test(); // prints "subTest Child"
    }
}

Here is what happens when you call superClass processFile method on your subClass instance:
your this reference across this call will refer to your subClass instance, always resulting in polymorphic call of subClass's methods if they are overriden.

Upvotes: 2

wxyz
wxyz

Reputation: 707

You can remove reportAction() from processFile() and call it separately if likely to change:

// super.java

public class Processor {
   public void process(String path) {
      File file = new File(path);

      // some code
      // ...

      processFile(file);
      reportAction(file.name());


   }
   protected void processFile(File file) {
      // some code
      // ...

   }
   protected void reportAction(String path) {
      System.out.println("processing: " + path);
   }
}


// child.java

public class BatchProcessor extends Processor {
   public void process(String path) {
      File folder = new File(path);
      File[] contents = folder.listFiles();
      int i;

      // some code
      // ...

      for (i = 0; i < contents.length; i++) 
      {
          super.processFile(file);
          reportAction(file.name());
       } 
   }
   protected void reportAction(String path) {
      System.out.println("batch processing: " + path);
   }
}

Upvotes: 0

Related Questions