-1

Example:

class Parent { constructor() {} }  
class Child { constructor() { super(); someChildCode(); } }   

I just want to execute some code after someChildCode(). Yes, I can place it there, but requirement is not placing that code there.

Because there are too many (n) child classes, and only one Parent, thus I want to not duplicate code (n) times.

P.S. I want clean code solution as simple as new Child() when creating child objects.

P.S. Downvoter, care to explain? I realise that the task may not be solvable, that is why I have asked the question, to be sure if that's the case.

Nurbol Alpysbayev
  • 19,522
  • 3
  • 54
  • 89

3 Answers3

1

If you really need the exact same code to run in every child class upon construction, then that common code probably belongs in the parent constructor. But maybe you need some child-specific code to run before the common code, in which case you still have an issue.

Either way, one possible solution would be not to override the constructor in the child classes at all, but instead let them inherit the parent constructor, which contains any common code as well as pre- and post- hooks you can override in child classes as necessary. For example:

class Parent {

    // do not override the constructor, conceptually "final"        
    constructor() {
        this.beforeCommonConstructorCode();

        // add any common constructor code here
        console.log("Common constructor code")

        this.afterCommonConstructorCode();
    }

    // override this in child classes as needed
    public beforeCommonConstructorCode() {
        // empty
    }

    // override this in child classes as needed
    public afterCommonConstructorCode() {
        // empty
    }
}

new Parent();
// in console:
// >> Common constructor code

And when you subclass Parent, you leave the constructor alone and add code to the appropriate methods:

class Child extends Parent {

    // remember, do not override constructor

    public beforeCommonConstructorCode() {
        console.log("Child pre-constructor code")
    }

    public afterCommonConstructorCode() {
        console.log("Child post-constructor code")
    }

}

new Child();
// in console:
// >> Child pre-constructor code
// >> Common constructor code
// >> Child post-constructor code

Note that TypeScript will not prevent child classes from overriding the constructor (there is no "final" keyword or functionality) so discipline is needed. Otherwise, I think this behaves the way you like; you are freed from having to place common code in each subclass.

Hope that helps. Good luck.

jcalz
  • 264,269
  • 27
  • 359
  • 360
  • Your answer is definitely the best to date. And it totally technically answers the question! However, there is one more detail, that I did not reveal in order to keep question simple. The child constructor is always there, because it is compiled automatically by typescript compiler (TSC). TSC also places there default property definitions (this.prop = {defaultValue}), after which I wanted to execute common parent code. Anyway, I am going to select your answer as correct, because it is. My fault that the question was not comprehensive. Thanks anyway, for your time :) – Nurbol Alpysbayev Apr 04 '18 at 14:29
0

If I understand this correctly, you can have an intermediate parent to achieve this given your code is generic and does not depend on child.

class Parent(){
}
class InterMediateParent extends Parent{
   constructor(){
      super();
      someCode();
   }

}

class Child extends InterMediateParent{
    constructor(){
     super();
    }

}
khawar jamil
  • 166
  • 4
  • Thanks, but someCode() still executes before the code, that I want to execute (someChildCode()) – Nurbol Alpysbayev Apr 04 '18 at 09:03
  • Will this work... class Parent{ someCode(){ console.log("somecode"); } } class Child extends Parent{ constructor(){ super(); super.someCode() console.log("childCode"); } } – khawar jamil Apr 04 '18 at 09:18
0

You can add that function to the Parent prototype so that only one copy is maintained across all child objects and call that function in child's constructor.

class Parent { 
  constructor() {
  
  } 
} 

Parent.prototype.someCommonCode = function() {
  console.log("Common code for all Parent as well as it's child objects");
}

class Child extends Parent {
  constructor() {
    //Child class code
    super();
    
    //Some child code
    this.someChildCode();
    
    //Call Parent's common function
    super.someCommonCode();
  }
  
  someChildCode() {
     console.log("Some child code");
  }
}

let child1 = new Child();
let child2 = new Child();
Vishal-L
  • 1,307
  • 1
  • 9
  • 16
  • Thanks, but you missed this part " ...execute some code after someChildCode(). Yes, I can place it there, but requirement is not placing that code there..." – Nurbol Alpysbayev Apr 04 '18 at 09:01
  • @NurbolAlpysbayev, I have edited the code. I hope this is what you need, if not be more clear about what you want and edit the question. – Vishal-L Apr 04 '18 at 09:10