import testing.*; class Pizza { ToppingList toppings; boolean deepDish; Pizza( ToppingList toppings, boolean deepDish ) { this.toppings = toppings; this.deepDish = deepDish; } //new Pizza(new EmptyTL(), true).fullPrice() -> 4.5 //new Pizza(new LargerTL(new Pepperoni(1),new EmptyTL()), false).fullPrice() -> 3.1 //To calculate the total price of this Pizza double fullPrice() { // ... this.deepDish ... this.toppings.ToppingMethod() ... return this.basePrice() + this.toppings.totalPrice(); } //new Pizza(new EmptyTL(), false).basePrice() -> 3.0 //new Pizza(new EmptyTL(), true).basePrice() -> 4.5 //To calculate the price of this Pizza without regard for toppings double basePrice() { // ... this.toppings.ToppingListMethod() ... this.deepDish ... if (this.deepDish) return 4.5; else return 3.0; } //To produce a pizza like this Pizza with no meat Pizza vege() { } } abstract class Topping { //To calculate the price of this Topping abstract double price(); //To determine if this Topping is vegetarian abstract boolean isVege(); } class GreenPepper extends Topping { double amt; GreenPepper(double amt) { this.amt = amt; } //new GreenPepper(1.0).price() -> .75 //To calculate the price of this GreenPepper double price() { //... this.amt ... return this.amt * .75; } //new GreenPepper(1.0).isVege() == true //To determine if this GreenPepper is vegetarian boolean isVege() { // ,,, this.amt ... return true; } } class Pepperoni extends Topping { int slices; Pepperoni(int slices) { this.slices = slices; } //new Pepperoni(1).price = .1 //To calculate the price of this Pepperoni double price() { // ... this.slices ... return this.slices * .1; } //new Pepperoni(1).isVege() == false //To determine if this Pepperoni is vegetarian boolean isVege() { // ... this.slices ... return false; } } abstract class ToppingList { //To calculate the total price of this ToppingList abstract double totalPrice(); //To produce a ToppingList with only vege toppings from this ToppingList abstract ToppingList makeVege(); } class EmptyTL extends ToppingList { EmptyTL() { } //new EmptyTL().totalPrice() -> 0 //To calculate the total price of this EmptyTL double totalPrice() { // ... return 0; } // new EmptyTL().makeVege() -> new EmptyTL() //To produce a ToppingList with only vege toppings from this EmptyTL ToppingList makeVege() { // ... return new EmptyTL(); } } class LargerTL extends ToppingList { Topping front; ToppingList rest; LargerTL( Topping front, ToppingList rest ) { this.front = front; this.rest = rest; } //new LargerTL(new GreenPepper(2.0), new LargerTL( new Pepperoni(5), new EmptyTL())).totalPrice() -> 2.0 //To calculate the total price of this LargerTL double totalPrice() { // ... this.front.ToppingMethod() ... this.rest.ToppingMethod() ... return this.front.price() + this.rest.totalPrice(); } //new LargerTL(new GreenPepper(2.0), new EmptyTL()).makeVege() -> // new LargerTL( new GreenPepper(2.0), new EmptyTL()) //new LargerTL(new GreenPepper(2.0), new LargerTL( new Pepperoni(5), new EmptyTL())).makeVege() -> // new LargerTL( new GreenPepper(2.0), new EmptyTL()) //To produce a ToppingList with only vege toppings from this LargerTL ToppingList makeVege() { // ... this.front.ToppingMethod() ... this.rest.ToppingListMethod() ... if (this.front.isVege()) return new LargerTL( this.front, this.rest.makeVege() ); else return this.rest.makeVege(); } }