Assignment 6: Extending Classes
Solutions

The correct answers are in blue.

Read chapter 10 in your textbook and the lecture notes carefully then solve the following problems.

Warm-ups:

1. In an object-oriented traffic simulation system, we have the following classes:

Bicycle     is a  Vehicle 
Car         is a  Vehicle 
Coupe       is a  Car 
Minivan     is a  Truck 
Motorcycle  is a  Bicycle 
PickupTruck is a  Truck 
Sedan       is a  Car 
Truck       is a  Vehicle 
Vehicle     is an Object 
Draw an inheritance diagram that shows the relationships between these classes.


2. What inheritance relationships would you establish among the following classes:

DepartmentChair    
Secretary         is an Employee 
Lecture           is a  Class 
Professor         is an Instructor
Instructor        is an Employee 
GuestSpeaker      is a  Person 
ComputerLab       is a  Class 
TeachingAssistant is an Instructor 
Janitor           is an Employee 
Seminar           is a  Class 
Person            is an Object 
Class             is an Object 
Employee          is a  Person 


3. Define a class Employee and derive a class Programmer from it.

Here's the contract for Employer:

Employee(n, s) // construct an Employee w/ name n salary s
e.getName()    // return the name of e
e.getSalary()  // return the salary of e 
e.setSalary(s)  // set the salary of e to s
For class Programmer:
class Employee {
  String name; 
  int salary; 
  Employee(String name, int salary) { 
    this.name = name; 
    this.salary = salary;
  }
  String getName() {
    return name; 
  }
  int getSalary() {
    return salary; 
  }
  void setSalary(int newSalary) {
    salary = newSalary; 
  } 
}

class Programmer extends Employee {
  private String language; 
  Programmer (String name, int salary, String language) {
    super(name, salary); 
    this.language = language; 
  } 
  void setLanguage(String newLanguage) {
    language = newLanguage; 
  } 
  String getLanguage() {
    return language; 
  } 
}


Exercises:

4. Consider the following classes B and D:

class B {
  public B() { System.out.println("B()"); } 
  public B(int n) { System.out.println("B(" + n + ")"); } 
}

class D extends B {
  private B b; 
  public D() { System.out.println("D()"); } 
  public D(int n) {
    super(n); // this gets executed first [2] and note 
    // that the corresponding constructor from the superclass
    // will be called and B(3) is printed since n == 3
    b = new B(-n); // this comes next [3] 
    // when a new object is created the same constructor will 
    // be invoked, albeit for a different object, and B(-3) 
    // will be printed since n == 3 and -n == -3 
    System.out.println("D(" + n + ")"); // [3] and
    // finally this line prints D(3) and the original 
    // invocation is finished and our simple program ends 
  } 
}
What does the following program print and why?
public static void main(String[] args) {
  D d = new D(3); // it starts here [1]
}
Trace the program by hand to explain the mechanism and its output.
B(3)
B(-3)
D(3)


5. Trace the execution of the following program:

class B {
  public void print(int n) { 
    System.out.println(n); 
  }
}

class D extends B {
  public void print(int n) {
    if (n <= 1) super.print(n); 
    else if (n % 2 == 0) print(n / 2); 
    else print(3 * n + 1); 
  } 
} 

public static main(String[] args) {
  D d = new D(); 
  d.print(3); 
}
What does the program print and why?

Note: assume the main appears in a tester class.

The program prints 1.

The key is not to confuse print from class B with System.out.print or any other display function. The initial argument is 3, then the function is calling itself with 10, 5, 16, 8, 4, 2, and finally 1 at which point the print method from the superclass is invoked and that actually prints 1.


6. What is wrong with the following code?

class B {
  private int b; 
  public B(int n) { 
    b = n; 
  } 
  public void print() {
    System.out.println("B: " + b); 
  } 
}

class D extends B {
  private B c, b;
  // B has no b member otherwise 
  public D(int n) { 
    super(n); // since there is no no-arg
              // constructor in the superclass  
    b = new B(n); 
  }
  public void print(int n) {
    System.out.print(" D: "); 
    b.print(); 
    c.print(); 
  } 
}
How can you fix the errors?

It is unclear what the code tries to accomplish, but one can quickly see why it won't compile: it violates the constructor chaining rule, and it tries to use an instance variable, b, in class B which is not inherited nor defined. With the changes made the code compiles.

We are not concerned about any run-time errors.


7. Suppose that class D inherits from B.

Which of the following assignments are legal?

B b = new B(); // fine  
D d = new D(); // fine  
b = d;         // I can use child where I can use parent  

d = b;         // these two statements won't compile since 
d = new B();   // we're asking for features (D d) that are
               // not part of the definition of class B 

b = new D();   // I can use child where I can use parent  


8. Trace the execution of the following program:

class B {
  public B() { }
  public void p() { System.out.println("B"); } 
}

class D extends B {
  public D() {}
  public void p() {
    super.p(); 
    System.out.println("D"); 
  } 
}

public static void main(String[] args) {
  B b = new B(); // prints nothing  
  D d = new D(); // prints nothing  
  b.p(); // b's print: prints B  
  d.p(); // d's print: prints B (super.p()) then D  
  b = d; // legal assignment, now b points to a D object  
  b.p(); // so again B and D will be printed  
}
What does the program print and why?

(Again assume that main is somewhere in a tester class.)

See the annotations in the code.


9. Assume you have the following in a file called One.java:

class A {
  double x; 
}

class B extends A {
  double x; 
  void show() {
    System.out.println(x + ", " + super.x); 
  }  
} 

public class One {
  public static void main(String[] args) {
    B m = new B(); 
    m.show(); 
    m.x = -1; 
    m.show(); 
    ((A)m).x = -1; 
    m.show();  
  } 
}
Questions:

1. How many instance variables does the object referred to by m in class One's main have (if any)?

The answer is: 2 instance variables both called x.

It has one as part of it being an object of type A and another one because it also is an object of type B.

2. Finish main such that all instance variables that belong to the object referred to by m are set to a particular value (for example, -1).

See annotated code above.

3. Add an instance method to class B that would list all the values of all the instance variables which the object referred to by m has, and use this method to check your work on m at question 2 above.

See annotated code above.

This problem actually part of lecture notes 12.

You see that we can access the variables both from the outside and from the inside of the class.


10. Consider the following program in a file Two.java:

class A {
  void fun() { System.out.println("Defined in A"); } 
}

class B extends A {
  void fun() { System.out.println("Defined in B"); } 
}

public class Two {
  public static void main(String[] args) {
    B m = new B(); 
    A n = new B(); 
    m.fun(); 
    n.fun(); 
    ((A)m).fun(); 
  } 
}
Questions:

1. What's the output of the program after you compile it and run it? Explain how that happens.

The fun() in B is called each time. The type of the reference is checked first and if it differs from the type of the object the object's type has priority in determining the function that is called, if a method member with that name is defined in both the type of the reference and the type of the object.

2. Is there any way you can change main such that using object reference m (which is of type B) you obtain the string Defined in A in the output through an invocation of fun()? How would you do it?

No. That's called overridding.

3. Same question if you're allowed to use n (which is of type A). Would it make any difference? Why?

It does, because then we could work with an object of type A.

4. How many instance members does an object of type B have?

If it has as many as we can access the right answer is: 2 from the inside and 1 from the outside.

Inheritance, overriding of methods and shadowing of variables are also covered in the notes (11-12).


If you have any questions please let us know.