Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Help with Dan's Chapter 6, exam 1, question 8.

 
Bob Young
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well pardners, I need some help with Dan's Chapter 6, exam 1, question 8.
class A {
void m1(A a) {System.out.print("A");}
}
class B extends A {
void m1(B b) {System.out.print("B");}
}
class C extends B {
void m1(C c) {System.out.print("C");}
}
class D {
public static void main(String[] args) {
A c1 = new C();
A c2 = new C();
A c3 = new C();
C c4 = new C();
c1.m1(c4);
c2.m1(c4);
c3.m1(c4);
}
}
What is the result of attempting to compile and run the program?
a. Prints: AAA
b. Prints: ABC
c. Prints: CCC
d. Compile-time error.
e. Run-time error.
f. None of the above

My thinking for the code line: c1.m1(c4);
I know that the true class is of type C and I need to match the method from it and not use the method from the reference type. I therefore answered that the code would print CCC. With anticipation of success, I headed out to verify that I got the correct answer. But Nooooooooo (insert sound clip for shootout at the OK coral) the answer is not CCC but AAA.
I went back to my notes and text books and all had examples of polymorphism similar to the following:
class A {
void m1() {System.out.print("A");}
}
class B extends A {
void m1() {System.out.print("B");}
}
class C extends B {
void m1() {System.out.print("C");}
}
class D {
public static void main(String[] args) {
A c1 = new C();
A c2 = new C();
A c3 = new C();
C c4 = new C();
c1.m1();
c2.m1();
c3.m1();
}
}
This is just Dan's example with each method taking no arguments. This compiles and will print CCC.

Now good citizens and sheriffs of Java Ranch (heck I will even take an answer from the villian Dan himself :-) ) I need some clarification on polymorphism. I looked at Dan's remarks for the question and I can not understand how it works (I've included his remarks below). Comparing the two examples, how is the "normal" example of polymorphism different than Dan's question?
I will sit at the bar drinking the unbearable swill they serve here and await your answers. Thanks.
Dan's remarks to question 8:
Class A has only one implementation of method m1. Class B overloads method m1 with a second implementation. Class C overloads method m1 with a third implementation. Even though c1, c2 and c3 are all instances of class C, the reference type is always A so the overload methods declared in the subclasses are not accessible. For that reason, the implementation of method m1 declared in class A is always invoked.
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Keeping it to a minimum: This question, no polymorphism!
 
Arnold Kesselaar
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bob,
class A {
void m1(A a) {System.out.print("A");}
}
class B extends A {
void m1(B b) {System.out.print("B");}
}
class C extends B {
void m1(C c) {System.out.print("C");}
}
class D {
public static void main(String[] args) {
A c1 = new C();
A c2 = new C();
A c3 = new C();
C c4 = new C();
c1.m1(c4);
c2.m1(c4);
c3.m1(c4);
}
}
I think it works like this. For polymorphism to work the method has to be in the reference class AND the actual instance class. The only method that is in both class A and class C is:
void m1(A a)
Therefore AAA is printed out.
I hope this helps.
 
Dan Chisholm
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Howdy Pardner!
As Barry pointed out earlier, the question from my exam involves overloaded methods while the example that you have provided involves overridden methods. The behavior of the overloaded methods is as Arnold explained. Since the reference is of type A, the overloaded methods that are declared in classes B and C are not accessible.
 
Sarma Lolla
Ranch Hand
Posts: 203
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is too difficult to become DCJP...
 
Bob Young
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is there a doctor in the house? I need my eyes checked! I wanted this question to be a polymorphism question so bad that my mind just made it one. Thanks for clearing the trail grim from my eyes.
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bob, Dan Chisholm is devilishly cunning He often takes a problem which would work in exactly the way you think it looks as if it would, except he makes one or two subtle changes somewhere that tilts the whole table.
-Barry
[ March 06, 2003: Message edited by: Barry Gaunt ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
�The method resolution process takes place at compile time based on the declared types of the object reference and the argument values.
This process determines which form of a method should be invoked, but not which implementation of that method.
At run time the actual type of the object the method is invoked upon is used to find an implementation of the method that was determined at compile time.�
The Java Programming Language, Arnold, Gosling & Holmes, 6.9.1
* emphasis mine
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
JLS 15.12.1 Compile-Time Step 1: Determine Class or Interface to Search
The first step in processing a method invocation at compile time is to figure out the name of the method to be invoked and which class or interface to check for definitions of methods of that name.
...
In all other cases, the qualified name has the form FieldName . Identifier; then the name of the method is the Identifier and the class or interface to search is the declared type of the field named by the FieldName.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
15.12.2 Compile-Time Step 2: Determine Method Signature
�The second step searches the class or interface determined in the previous step for method declarations.
This step uses the name of the method and the types of the argument expressions to locate method declarations that are both applicable and accessible, that is, declarations that can be correctly invoked on the given arguments.

The class or interface determined by the process described in �15.12.1 is searched for all method declarations applicable to this method invocation; method definitions inherited from superclasses and superinterfaces are included in this search.�
If we use the lingo of the JLS, we would say, the overloaded methods that are declared in classes B and C are not applicable (instead of saying not accessible).
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
On re-reading JLS 15.12.2.1, I changed my mind. We wouldn�t say the overloaded methods declared in classes B and C are not applicable. Nor would we say they are not accessible.
We would say the overloaded methods declared in classes B and C are not members, declared or inherited, of the class determined in the first compile-time step, namely, class A.
Therefore, they are not considered in the second compile-time step to determine applicable and accessible method declarations.
[ March 06, 2003: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Some people might say polymorphism does not occur in this example. But I would say it does. A polymorphic variable is a variable that is declared as one type but in fact holds a value of a different type. The parameter in the method void m1(A a) is a polymorphic variable.
 
Dan Chisholm
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Marlene,
You've made some intertesting semantic arguments here. This would be a great time for James Gosling to step up to the bar and have a few drinks with us.
 
Dan Chisholm
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Bob Young:
Is there a doctor in the house? I need my eyes checked! I wanted this question to be a polymorphism question so bad that my mind just made it one. Thanks for clearing the trail grim from my eyes.

This dusty cow town doesn't have an ophthalmologist but we do have a dentist--Doc Holliday. Right about now you'll find him walking down to the O.K. Coral to see the Clanton boys.
[ March 07, 2003: Message edited by: Dan Chisholm ]
 
mohamed hamdy
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi,
to show that the answer of this quesion don't rely on the polymorphism, we can modify it to view what the polymorphis is :
class A {
void m1(C c) {System.out.print("A");}
}
class B extends A {
void m1(C c) {System.out.print("B");}
}
class C extends B {
void m1(C c) {System.out.print("C");}
}
public class D {
public static void main(String[] args) {
A c1 = new C();
A c2 = new C();
A c3 = new C();
C c4 = new C();
c1.m1(c4);
c2.m1(c4);
c3.m1(c4);
}
}
it'll print CCC
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic