atul
atul

Reputation: 600

Typescript multiple class inheritance design

I am designing a Menu system for a restaurent in Typescript. I have defined an interface to implement necessary function for each Menu Item :

interface HasPrice {
    getPrice(): number;
}

Each menu item is defined by a class.

class Gobi implements HasPrice {
    getPrice() : number {
        return 50;
    }
}

class FriedRice implements HasPrice {
    getPrice() : number {
        return 100;
    }
}

I am using decorator class to add toppings. eg.Fried Rice with chicken

class FriedRiceWithChicken implements HasPrice {
    getPrice() : number {
        return super.getPrice() + 25;
    }
}

Now I want to extend this system for combo menus. eg. Fried Rice + Gobi

class FriedRiceAndGobi extends FriedRice, Gobi {
    getPrice() : number {
        return FriedRice.getPrice() + Gobi.getPrice();
    }
}

How can I implement combo classes? Is there a way I can write a generic class/method to implement combo menu?

Upvotes: 2

Views: 643

Answers (1)

Evert
Evert

Reputation: 99505

Typescript does not have support for multiple inheritance.

There's a couple of different reasons why you would want multiple inheritance. Your example is however not one of them.

If, using your example, I would need a single class that encapsulates both ingredients, this is how I would approach this:

class CombinedItem {
   private menuItems: HasPrice[];
   constructor(menuItems: hasPrice[]) {
      this.menuItems = menuItems;
   }
   getPrice() {
      return this.menuItems.reduce(
         (acc, curr) => acc + curr.getPrice(),
         0
      );
    }
}

This could then be constructed as such:

const item = new CombinedItem([
   new Rice(),
   new Chicken()
]);

CombinedItem is a class that can take any combination of inputs. If you want something really specific, you can do:

class ChickenAndRice {
   private chicken: Chicken;
   private rice: Rice;
   constructor(chicken: Chicken, rice: Rice) {
      this.chicken = chicken;
      this.rice = rice;
   }
   getPrice() {
      return this.chicken.getPrice() + this.rice.getPrice();
    }
}

But I'm not sure why you would ever want this.

Thinking in the direction of inheritance for your problem is a common mistake, and right solution is to compose objects and classes together instead of inherit behavior.

Upvotes: 1

Related Questions