Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running a method after the constructor of any derived class

Tags:

java

oop

scala

Let's say I have a Java class

abstract class Base {     abstract void init();     ... } 

and I know every derived class will have to call init() after it's constructed. I could, of course, simply call it in the derived classes' constructors:

class Derived1 extends Base {     Derived1() {         ...         init();     } }  class Derived2 extends Base {     Derived2() {         ...         init();     } } 

but this breaks "don't repeat yourself" principle rather badly (and there are going to be many subclasses of Base). Of course, the init() call can't go into the Base() constructor, since it would be executed too early.

Any ideas how to bypass this problem? I would be quite happy to see a Scala solution, too.

UPDATE: Here is a generic version of the Factory Method approach:

interface Maker<T extends Base> {     T make(); }  class Base {     ...     static <T extends Base> T makeAndInit(Maker<T> maker) {         T result = maker.make();         result.init();         return result;     } } 

UPDATE 2: This question is basically "how do you use Template Method for constructors"? And the answer seems to be, "You can, but it's a bad idea". So I can do a Template Factory (Template Method + Abstract Factory) instead.

like image 511
Alexey Romanov Avatar asked May 25 '10 17:05

Alexey Romanov


People also ask

Can we use constructor in derived class?

If we inherit a class from another class and create an object of the derived class, it is clear that the default constructor of the derived class will be invoked but before that the default constructor of all of the base classes will be invoke, i.e the order of invocation is that the base class's default constructor ...

Do derived classes inherit methods?

Overriding Properties and Methods in Derived ClassesBy default, a derived class inherits properties and methods from its base class. If an inherited property or method has to behave differently in the derived class it can be overridden. That is, you can define a new implementation of the method in the derived class.

What happens in constructors in derived class?

The derived class takes the responsibility of supplying the initial values to its base class. The constructor of the derived class receives the entire list of required values as its argument and passes them on to the base constructor in the order in which they are declared in the derived class.

Can we override constructor in derived class?

a constructor cannot be overridden. a constructor cannot be called with an object but method can be called. To call a constructor, an object must be created.


1 Answers

Avoid this. If you do it, any class that extends your DerivedX class may decide to also call init() thus leaving the object in inconsistent state.

One approach is to let the init() method be invoked manually by clients of your class. Have an initialized field, and throw IllegalStateExcepion if any method that requires initialization is called without it.

A better approach would be to use a static factory method instead of constructors:

public Derived2 extends Base {     public static Derived2 create() {        Derived2 instance = new Dervied2();        instance.init();        return instance;     } } 

Update: As you suggest in your update, you can pass Builder to a static factory method, which will call the init() on the instance. If your subclasses are few, I think this is an overcomplication, though.

like image 156
Bozho Avatar answered Oct 06 '22 03:10

Bozho