1

I have lots of children to a base class and plan for adding a lot more. I'm lazy. The child creator sets up some basic things that is needed for the super constructor and vice versa. A simple solution from my problem would be the following:

parent {
   public parent(){/*some code*/}
   public void finalSetup(){/*code that dependent on the fact that the child constructor has run*/}
}
child{
    public child(){/*some code;*/ super.finalSetup();}
}

How ever, calling super.finalSetup() on every child is quite the hassle, and if I forget it on one it'll break. That's no good. My question is simple: is there any way to set this up form the parent. As far as my google skills go I haven't been able to find one. Hopefully you guys know something I don't.

Thanks

Daniel Hesslow
  • 359
  • 2
  • 10

3 Answers3

1

Consider the Factory pattern to create generic type that extends Parent.

public class Parent {
   public Parent(){/*some code*/}
   public void finalSetup(){/*code that dependent on the fact that the child constructor has run*/}

   public static <T extends Parent> T makeChild(Class <T> klass) {
        T child = null;
        try {
          child = klass.newInstance();
          child.finalSetup();
        } 
        catch (InstantiationException| IllegalAccessException ex) {
           // somthing went wrong
        }
        return child;
    }
}

and call

Child child = Parent.makeChild(Child.class);

It is useful when:
+ a class can't anticipate the class of objects it must create
+ a class wants its subclasses to specify the fields or objects it creates
+ classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate

MaxZoom
  • 7,619
  • 5
  • 28
  • 44
  • 1
    I tested the code myself and it works like a charm. In case someone wants to down vote it, please give a valid reason. – MaxZoom Jun 11 '15 at 22:40
0

This should do it. The basic idea is to override the before and after methods in your children and in the parent constructor you simply run both and do some initialization in between. Of course this does not save you from forgetting to call the parent constructor.

abstract class Parent {

    Parent(){
        doBefore();
        // some stuff
        doAfter();
    }

    abstract void doBefore();

    abstract void doAfter();


}

class Child extends Parent {

    Child(){
        super();
    }

    void doBefore(){
        // do before stuff
    }

    void doAfter(){
        // do after stuff
    }
}

With abstract methods in your parent you can implement any permutation of before / after procedures.

Adam Arold
  • 29,285
  • 22
  • 112
  • 207
  • He wants to have parent constructor finished first, call the child constructor and then call `finalSetup()`. – MaxZoom Jun 10 '15 at 16:36
  • `doBefore` is there to be a replacement for the child constructor. – Adam Arold Jun 10 '15 at 16:38
  • This is going to lead to all sorts of problems: http://stackoverflow.com/questions/3404301/whats-wrong-with-overridable-method-calls-in-constructors – Sotirios Delimanolis Jun 10 '15 at 16:41
  • AFAIK in Java parent object is created before the child object creation is completed. – MaxZoom Jun 10 '15 at 16:42
  • There is only one object created. This is how inheritance works. – Adam Arold Jun 11 '15 at 08:17
  • @SotiriosDelimanolis I don't think that you should blindly follow any rule. The link you provided says that it is a possibility that you will have problems. I used this model in the past and I never had any bugs because of it. You just simply have to be aware of what does what and how and you will be fine. – Adam Arold Jun 11 '15 at 08:19
0

This should be what you want, but as already mentioned, it can be not the best idea. You don't need to explicitly call the parent constructor in your subclass if you have a no-argument constructor in your superclass.

abstract class Parent {
    Parent() {
        /*some code*/
        childInit();
        finalSetup();
    }
    void finalSetup() {/*code that dependent on the fact that the child constructor has run*/}
    abstract void childInit();
}

class Child extends Parent {
    @Override
    void childInit() {
        /* the code you would put in child's constructor */
    }
}
Community
  • 1
  • 1
John29
  • 3,340
  • 3
  • 32
  • 50