// OOP approach to food orders - Using the Factory Method Design Pattern import java.util.ArrayList; // built-in extendable list // base abstract class for all food objects: abstract class food { //// data structures and methods common to all subclasses: protected ArrayList Ingredients = new ArrayList(); protected int cals; // variables can't be overriden public void printingredients() { for(String i:Ingredients) System.out.print(i+" "); System.out.println(); } public int calories() {return cals;} //// abstract methods to be defined in concrete subclasses: public abstract void make(); // The "factory method" public abstract double price(); } // If an abstract class contains only abstract method declarations, it's // better to use an interface instead. class pizza extends food { public pizza() // constructor { Ingredients.add("dough"); Ingredients.add("tomato sauce"); Ingredients.add("cheese"); cals = 1000; // default - can be changed /**** most important line ****/ make(); // dispatches to subclass make method bake(); }//constructor public void make() { } // default make does nothing public void bake() { /* zzzzzzz */ } public double price() {return 10.00; } }// basic cheese pizza class class cheesepizza extends pizza {} //just an alias for pizza? what for? class pepperonipizza extends pizza { public pepperonipizza() { super(); } // not needed (default constructor) public void make() { // superclass constructor made basic cheese pizza Ingredients.add("pepperoni"); cals = 1400; } public double price() {return 12.00;} } class hawaiian extends pizza // add another kind of pizza { public void make() { Ingredients.add("canadian bacon"); Ingredients.add("pineapple"); cals = 1200; } public double price() {return 14.00;} // override } abstract class sandwich extends food { public boolean mayo; // no more mayo on pizza } // sandwich is still abstract: can't create new sandwich() class hamandcheese extends sandwich { public hamandcheese(boolean m) { make(); mayo=m; } // constructor calls make public void make() { Ingredients.add("bread"); Ingredients.add("ham"); Ingredients.add("cheese"); } public int calories() { return 600; } // can also override non-abstracts. public double price() { return 2.0 * Ingredients.size(); } }//hamandcheese sandwich class blt extends sandwich { public blt() {make();} public void make() { Ingredients.add("bread"); Ingredients.add("bacon"); Ingredients.add("lettuce"); Ingredients.add("tomato"); cals = 800; } public double price() {return 8.00;} }//blt sandwich ///// and now for a whole new category of food: abstract class soup extends food // still abstract because of price func. { public void make() { Ingredients.add("broth"); } } class chickennoodle extends soup { public void make() { super.make(); // calls immediate superclass version of make Ingredients.add("chicken"); Ingredients.add("noodles"); } public double price() { return 3.50; } } public class oopfood { public static void main(String[] args) { ArrayList myorder = new ArrayList(); ArrayList yourorder = new ArrayList(); myorder.add(new cheesepizza()); myorder.add(new hawaiian()); myorder.add(new hamandcheese(true)); myorder.add(new chickennoodle()); for (int i=0;i<10;i++) yourorder.add(new pepperonipizza()); for (int i=0;i<20;i++) yourorder.add(new blt()); double mycost = 0, yourcost = 0; for(food item:myorder) mycost += item.price(); for(food item:yourorder) yourcost += item.price(); System.out.printf("my order costs %.2f\n",mycost); System.out.printf("your order costs %.2f\n",yourcost); // what about THINGS THAT SHOULDN'T WORK? //myorder.add(new chesspizza()); // compiler error, pizza yourlunch = new pepperonipizza(); //yourlunch.mayo = true; // compiler error - thank goodness }//main }