/* Question 1: 1. Expected : 49.95 Actual : 49.95 Why : A velvet non-wheeled chair was created, and the price method was called 2. Expected : Associate the name f with the value of a velvet non-wheeled chair. f has type Furniture Acutal : no visible result Why : f is associated, nothing to report 3. Expected : 49.95 Actual : 49.95 Why : f, as a Furniture, has a price method. The price of the chair is unchanged from 1 4. Expected : an error reporting that Furniture has no hasWheels field Acutal : an error reporting that Furniture has no hasWheels field Why : f has type Furniture, which only has a price method. We cannot access a field of Chair when Java does not know that f is a Chair. 5. Expected : A velvet non-wheeled chair Actual : Chair( hasWheels = false, covering = "velvet") Why : Made a Larger with f as the first and Empty as the rest, accessed the first field of Larger 6. Expected : Associated the name myL with the value of the Larger from 5. myL has type List Actual : no visible result Why : myL is associated 7. Expected : an error Actual : an error reporting that List has no first field Why : myL has type List, which does not have the mentioned field, therefore we cannot access it 8. Expected A list with myL as the first element and f as the second Actual : Same as expected Why : A Larger can accept an Object for the first element. A List is an Object, and so an instance of a List can be an element of another List */ //2 abstract class EmployeeL { //To produce a sorted EmployeeL from this one abstract EmployeeL sort(); //To produce an EmployeeL with e in the proper place //Expects a sorted EmployeeL abstract EmployeeL insert( Employee e ); } class EmptyEL extends EmployeeL { EmptyEL() { } //To produce a sorted EmployeeL from this one EmployeeL sort() { return this; } //new Empty().insert(new Temp(5,3)) -> new Larger(new Temp(5,3),new Empty()) //To produce a sorted EmployeeL with e in the proper place EmployeeL insert( Employee e ) { //.. e.EmplyeeMethod( ) ... return new LargerEL( e, this ); } } class LargerEL extends EmployeeL { Employee first; EmployeeL rest; LargerEL( Employee first, EmployeeL rest ) { this.first = first; this.rest = rest; } //new LargerEL(new Temp(3,4), new LargerEL(new Temp(2,1), new EmptyEL())).sort() -> // new LargerEL(new Temp(2,1), new LargerEL( new Temp(3,4), new EmptyEL())) //To produce a sorted EmployeeL from this one EmployeeL sort() { // ... this.first.EmployeeMethod() ... this.rest.EmployeeELMethod()... return this.rest.sort().insert(this.first); } //new LargerEL(new Temp(2,1), new EmptyEL()).insert(new Temp(3,4)) -> // new LargerEL(new Temp(2,1), new LargerEL( new Temp(3,4), new EmptyEL())) //To produce a sorted EmployeeL with e in the proper place EmployeeL insert( Employee e ) { //... this.first.EmployeeMethod() ... this.rest.EmployeeELMethod()... e.EmplyeeMethod( ) ... if (this.first.salary() > e.salary()) return new LargerEL(e, this); else return new LargerEL(this.first, this.rest.insert(e)); } } abstract class Employee { abstract double salary(); } class Temp extends Employee { int hours; double rate; Temp( int hours, double rate) { this.hours = hours; this.rate = rate; } double salary() { return this.rate * this.hours; } } interface Totalable { // Provide a value for the total of a List int getInt(); } class Fish implements Totalable { int weight; Fish( int weight ) { this.weight = weight; } //Provide a value for the total of a List of Fish int getInt() { return this.weight; } } //4 abstract class ListT implements Totalable{ // To return the total of the elements in the list abstract int total(); //Provide a value for the total of a List of ListT int getInt() { return this.total(); } } class EmptyLT extends ListT { //To return the total of the elements in the list int total() { return 0; } } class LargerLT extends ListT { Totalable first; ListT rest; LargerLT( Totalable first, ListT rest ) { this.first = first; this.rest = rest; } //Tp return the total of elements in the list int total() { // ... this.first.TotalableMethod() .. this.rest.ListTMethod() .. return this.first.getInt() + this.rest.total(); } } //5 abstract class Expression { //To create a List of all of the vars seen in this expression abstract List getVars(); } class Num extends Expression { int val; Num( int val ) { this.val = val; } //To create a List of all of the vars //new Num(3).getVars() -> new Empty() List getVars() { // ... this.val ... return new Empty(); } } class Var extends Expression { String name; Var( String name ) { this.name = name; } //new Var("x").getVars() -> new Larger("x",new Empty()) //To create a List of all of the vars List getVars() { // .. thisl.name ... return new Larger( this.name, new Empty() ); } } class Operation extends Expression { String op; Expression left, right; Operation( String op, Expression left, Expression right ) { this.op = op; this.left = left; this.right = right; } //new Operation("+",new Var("x"),new Num(1)).getVars -> // new Larger("x",new Empty()) //To create a List of all of the vars List getVars() { // ... this.left.ExpressionMethod() .. this.right.ExpressionMethod() ... this.op return this.left.getVars().append(this.right.getVars()); } } abstract class List { //Put two lists together abstract List append( List l); } class Empty extends List { //Put two lists together // new Empty().append(Empty()) -> new Empty() List append( List l) { return l; } } class Larger extends List { Object first; List rest; Larger( Object first, List rest ) { this.first = first; this.rest = rest; } //To put two lists together List append( List l ) { // ... this.first ... this.rest.ListMethod() return new Larger( this.first, this.rest.append(l)); } }