// OOP approach to food orders - Using the Factory Method Design Pattern import java.util.*; // 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 }//constructor public void make() { } // default make does nothing 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 { 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 pizzas } // sandwich type 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(); } } 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;} } //////////////////// class for an "order" of food, as used by takeout class order { public String customer; // customer who made order. public order(String c) {customer=c;} public ArrayList Fs = new ArrayList(); public void add(food x) { Fs.add(x); if (x.calories()>1000) System.out.println("Warning: eating "+x+" is probably not good for your health"); } public double totalprice() // polymorphic procedure { double ax = 0; for(food item:Fs) ax += item.price(); return ax; } } public class foodfactory { public static void main(String[] args) { order myorder = new order("hungry prof"); order yourorder = new order("starving student"); myorder.add(new cheesepizza()); myorder.add(new hawaiian()); myorder.add(new hamandcheese(true)); for (int i=0;i<10;i++) yourorder.add(new pepperonipizza()); for (int i=0;i<20;i++) yourorder.add(new blt()); System.out.printf("my order costs %.2f\n",myorder.totalprice()); System.out.printf("your order costs %.2f\n",yourorder.totalprice()); // what about THINGS THAT SHOULDN'T WORK? //myorder.add(new chesspizza()); // compiler error pizza yourlunch = new pepperonipizza(); //yourlunch.mayo = true; // compiler error - thank goodness } }