javascriptjavascript-objectsjavascript-inheritance

How to use one class to extend multiple classes (not multiple inheritance)?


Here's a couple of JS classes. The GrandChildOne and GrandChildTwo classes are identical, but extend different parent classes. Since their code is identical I'm looking for ways to get rid of this duplication. In other words, I'd like to have one class (let's call it GrandChild) and use it to extend ChildOne and ChildTwo classes. Any advice?

class Parent {
  someParentMethod () {
     console.log('Parent')
  }
}

class ChildOne extends Parent {
   someChildOneMethod () {
     console.log('someChildOneMethod')
  }
}

class ChildTwo extends Parent {
   someChildTwoMethod () {
     console.log('someChildTwoMethod')
   }
}


// THE CLASSES BELOW ARE IDENTICAL
class GrandChildOne extends ChildOne {
   someGrandChildMethod() {
     console.log('someGrandChildMethod')
   }
}
class GrandChildTwo extends ChildTwo {
   someGrandChildMethod() {
     console.log('someGrandChildMethod')
   }
}

const grandChildOne = new GrandChildOne()
const grandChildTwo = new GrandChildTwo()

Solution

  • You could use Mix-ins for this (example in MDN)

    It would be something like this:

    class Parent {
      someParentMethod () {
         console.log('Parent')
      }
    }
    
    class ChildOne extends Parent {
       someChildOneMethod () {
         console.log('someChildOneMethod')
      }
    }
    
    class ChildTwo extends Parent {
       someChildTwoMethod () {
         console.log('someChildTwoMethod')
       }
    }
    
    
    // define GrandChild as a Mix-in:
    let GrandChild = Base => class extends Base {
      someGrandChildMethod() {
         console.log('someGrandChildMethod')
       }
    };
    
    //Then:
    class GrandChildOne extends GrandChild(ChildOne) { }
    class GrandChildTwo extends GrandChild(ChildTwo) { }
    
    const grandChildOne = new GrandChildOne()
    const grandChildTwo = new GrandChildTwo()
    
    grandChildOne.someChildOneMethod();
    grandChildTwo.someChildTwoMethod();