How to call in the abstract class the constructor of the class that specifically inherits it? Type of such:

public abstract class AbstractClass { public Abstract foo() { //Когда метод foo вызовется наследником AbstractClass a = new this(); //здесь надо вызвать конструктор наследника a.bar(); //как-то меняем состояние, вызывая метод наследника return a; //и возвращаем экземпляр наследника } public abstract void bar(); } 

But in this example, it gives an error:

java: as it is release 8

  • one
    Either you got lost in three pines, or I didn't understand the question. Why do you need to create an instance of a successor if the foo() method is already an instance method? Take an instance of the heir and just call its foo() method. And even better, bar() right away. - andreycha
  • four
    @NikBond The basic and, moreover, abstract class knows nothing about its heirs and moreover does not need to know. If you have such a problem, then you have incorrectly designed classes. - Vlad from Moscow
  • @VladfromMoscow I just need the base class to perform actions that are the same type for all heirs, without information from who specifically inherits it. Those. when a method of a base abstract class calls a specific heir, the heir could create an instance of its class, as described in the method. Doesn't that fit into a good design? - NikBond
  • one
    TC need virtual cloning or virtual factory method - NewInstance. - Igor
  • one
    instead of new this() try getClass().newInstance() - Chubatiy

1 answer 1

First of all, in a good design, the base class should not know anything about its heirs, otherwise one of the foundations of OOP about contract programming is broken.

Make another abstract method and override it in the inheritors so that they return new instances of their type:

 public abstract class AbstractClass { public AbstractClass foo() { AbstractClass a = createInstance(); a.bar(); return a; } public abstract void bar(); protected abstract AbstractClass createInstance(); } public class ConcreteClass extends AbstractClass { protected override AbstractClass createInstance() { return ConcreteClass(); } } 

If you still do not want to touch the heirs and go the dirty way, then you can use reflection (however, in this case, all the heirs should have a constructor without parameters):

 public Abstract foo() { AbstractClass a = this.getClass().newInstance(); a.bar(); return a; }