Can derived classes call the constructor of their abtract-father classes, that call their not yet implemented methods?

StackOverflow https://stackoverflow.com/questions/22799389

Question

I have a java question. I want to create an abstract class that have some abstract methods. In the abstract class constructor, i want to call these abstract methods.

The classes that extend this abstract class have to implement the abstract methods, and the only thing they have to do, is to call the abstract class constructor in their own constructor ( with super() keyword ).

If it sounds a little complicated here is an example of what i want to do (my apologies if there are any syntax errors, i wrote this example in notepad):

public abstract class DarthVader{

    public DarthVader() {
        System.out.println("Luke, I am your father!");

        method1();
        method2();
    }

    public abstract void method1();
    public abstract void method2(); 
}

...

public class Jedi extends DarthVader {

    public Jedi() {
        super();
    }

    public void method1() {
        System.out.println("I am a true jedi");
    }

    public void method2() {
        System.out.println("Prepare to die!");
    }
}

...

public class Sith extends DarthVader  {

    public Sith() {
        super();
    }

    public void method1() {
        System.out.println("Hello dad");
    }

    public void method2() {
        System.out.println("Sith Lords Rule!");
    }
}

So, i want the only responsibility for the child classes to be:

1) The implementation of the abstract methods

2) Call the super-conctructor (i do not want them to have to decide what methods should be called)

Is this possible?

  • PS: if the title does not reflect what i want to ask, feel free to suggest an other one!
Was it helpful?

Solution 2

->Is this possible?

Yes, of course. As long as your child classes implement all the abstract methods.

Actually this is the concept Polymorphism :Polymorphism is the provision of a single interface to entities of different types.

Ref to your code, the hierarchy is:

   DarthVader
        │
       ─┴─
      │   │
    Jedi Sith

In DarthVader you declared two abstract method: method1() and method2(). Then you have their implementation in child classes.

Polymorphism is that you use the abstract reference to point to an implementation class object. Like this:

DarthVader j = new Jedi();
j.method1();

For the JVM, it will correctly call the method1() in Jedi. This concept is called Dynamic dispatch. In modern languages, it's implemented by vTable.

You can take a look at the references.

OTHER TIPS

This is allowed, but there is grave danger associated with it and some compilers will give you a warning. It has nothing to do with the super class being abstract, or the methods being abstract. It has to do with base class calling non-final methods.

Consider the following:

class Base {
  SomeObject s;
  Base() { s = new SomeObject(); foo(); }
  void foo() { s.someMethod(); }
}

class Der {
  SomeOtherObject o;
  Der() { super(); o = new new SomeOtherObject();}
  @Override foo() { o.someOtherMethod(); }
}

What happens when Der is created?

  1. Der() is called
  2. Base() is called
  3. Base.s is initialized
  4. foo() is called
  5. Call is dispatched to Der.foo()
  6. Der.foo calls o.someOtherMethod

At this point Der.o is null and you get a NullPointerException

(Virtual member call in a constructor)[Virtual member call in a constructor has a nice explanation of the topic. It is for C# but applies just as well to java.

Yeah. By virtual method dispatch, calling a method (even calling a method of this from a supertype, as in this question) invokes the code of the derived type.

(edit)

To relate this to a setting that people are probably more comfortable with, consider

List a = new ArrayList();
int n = a.size();

The .size() calls ArrayList's implementation--even though a is declared as List, it is an ArrayList at runtime.

Within the constructor of the abstract class, this is (implicitly) declared as a DarthVader, but at runtime, it can be an instance of a derive type (in this case, it must be, since DarthVader is abstract). Thus method1() and method2() succeed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top