class A { public int m1 (int n) { return n+2; } public int m2 (int n) { return n*2; } public int m3 (int n) { return n/2; } public int m4 (int n) { return m1(n) + m2(n); } } |
class B extends A { protected int j; public B () { j=10; } public B (int n) { j=n; } public int m1 (int n) { return super.m3(n); } public int m3 (int n) { return n - 2; } public int m5 (int n) { return m3(n) + super.m3(n); } } |
class C extends B { protected int k; public C () { this(4,5); // must be first line in method } public C (int k) { this.k = k; } public C (int j, int k) { super(j); // must be first line in method this.k = k; } public int m2 (int n) { return n*3; } } |
class D extends B { public D (int k) { super(k); // must be first line in method } public int m2 (int n) { return n + j; } public int m3 (int n) { return n + 4; } public int m6 (int n) { return m3(n) + super.m3(n); } } |
class E extends D { public E () { super(8); // why is this line required? } } |
Draw an inheritance diagram for the five classes and draw invocation trees and objects in ObjectLand for each statement below. In the invocation tree, specify which version of each method is being invoked by labelling the invocation tree node by the class name. The invocation tree should include nodes for all methods invoked for each statement. You can ignore the this in each node.
A instanceA = new A(); instanceA.m4(10); B instanceB1 = new B(); B instanceB2 = new B(8); instanceB2.m4(10); instanceB2.m5(10); C instanceC1 = new C(); C instanceC2 = new C(5); (new C(8,4)).m4(10); D instanceD = new D(8); instanceD.m4(10); instanceD.m5(10); instanceD.m6(10); E instanceE = new E(); instanceE.m4(10); instanceE.m5(10); instanceE.m6(10);