One answer has already been given to you, I will try to provide some logical alternative.
First, the "First", "Second" or "Third" is too weak a sign to use for this inheritance (otherwise any addition of the "Dessert" or the abstract "Fourth" dish) will result in the need to create a new basic object . Thus, it is a property of a particular object .
Further, the program design is built as follows (in general, speaking, the name of the product can also be made a property and avoid inheritance in general, but here, probably, the example will look better with inheritance than without it):
public abstract class Portion { // Технические детали можете додумать самостоятельно :) public PortionType getType() { ... } } // Реализуем так, что тип данной порции = "Первое" public class Cheesburger : public Portion { ... } // Реализуем так, что тип данной порции = "Десерт" public class CocaCola : public Portion { ... }
Now let's think about how we imagine lunch. "Lunch" is a collection of servings, organized as follows, so that the specified conditions are fulfilled (in your case, it consists of exactly three dishes of known types) .
public class Meal { public List<Portion> getPortions() { ... } }
The question is how to allow the creation of those and only those meals that satisfy the conditions you set out. The solution is also easy - we prohibit the construction of the Meal object through its constructor, and we introduce for this purpose some abstract factory.
A possible interface might look like this:
public class MealFactory { // Построим, например, по методу 'first fit'. public Meal buildFirstFitMealFromAvailablePortions(List<Portion> availablePortions) throws ImpossibleToBuildMealException { ... } // А здесь передадим как параметр некоторое правило построения обедов. public Meal buildMealFromAvailablePortions(List<Portion> availablePortion, MealBuildingRule buildingRule) throws ImpossibleToBuildMealException { ... } }
Here, too, there are options - you can bind strategies directly to the builder or even use some method of dependency injection.
By the way, as an alternative to the factory, it is possible to consider the Pattern Builder , which is well discussed in the book Effective Java.