aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes About Overridden II (a Mock Question question...) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "About Overridden II (a Mock Question question...)" Watch "About Overridden II (a Mock Question question...)" New topic
Author

About Overridden II (a Mock Question question...)

Karin Paola Illuminate
Ranch Hand

Joined: Oct 18, 2002
Posts: 109
Mock Question :
What is displayed when the following is executed?

Compile time error
Runtime error
Prints "Parent's method2() Parent's method1()"
Prints "Parent's method2() Child's method1()"
Correct Answer:
"Prints "Parent's method2() Parent's method1()"" is correct !
(Part of) Explaination:
(...) Now from the method2() , there is a call to method1(). Please note that method1() of Parent class is private, because of which the same method (method1() of Parent class) will be invoked. Had this method(method1() of Parent class) been public/protected/friendly (default), Child's class method1() would be called (...)
My question is:
why does the output depend on the access modifier of method1() of Parent class? Why would the Child's class method1() be called, if the access modifier of method1() of Parent class was NOT private???
I don't understand.
Karin
[ Jess added UBB [code] tags to preserve whitespace -- check 'em out! ]
[ November 18, 2002: Message edited by: Jessica Sant ]

I not only use all the brains that I have, but all that I can borrow. [Laurence J. Peter]
Peter Tran
Greenhorn

Joined: Oct 17, 2002
Posts: 25
At run-time class Child inherited method2 from the Parent class. You are running the method2 from Parent which in turn run the method1 from Parent. Method2 from Parent when compiled resolved to bind with Method1 also from Parent.
I hope that help...


SCJP 1.4, SCSA 8.0, CCNA<br />IBM Certified Specialist AIX<br />Microsoft MCSD
Karin Paola Illuminate
Ranch Hand

Joined: Oct 18, 2002
Posts: 109
Thanks. But, I still don't understand the explaination of the Mock Question.
If I change the access modifier from private into public, the Child's class method1() is called, and not the Parent's class method1()? Do you know the reason for this?
Peter Tran
Greenhorn

Joined: Oct 17, 2002
Posts: 25
Ok I was kind of forgot about the access modifier. When a method is declared "private" it cannot be override by a subclass. A subclass can give it own declaration but that is just overshadow not override. Since method1 was private and when you invoke the parent.method2, method1 is visible in the parent class.
After changing the modifier to public, method1 is now correctly override by the Child.method1.
At runtime, the dynamic method lookup will correctly invoke Child.method1
david eberhardt
Ranch Hand

Joined: Jul 02, 2002
Posts: 158
just when I thought I was ready for exam questions on this topic!
I'm looking at ]15.11.4 Runtime Evaluation of Method Invocation
15.11.4 Runtime Evaluation of Method Invocation
At run time, method invocation requires five steps. First, a target reference may be computed. Second, the argument expressions are evaluated. Third,
the accessibility of the method to be invoked is checked. Fourth, the actual code for the method to be executed is located. Fifth, a new activation frame
is created, synchronization is performed if necessary, and control is transferred to the method code.
david eberhardt
Ranch Hand

Joined: Jul 02, 2002
Posts: 158

Compile time error
Runtime error
Prints "Parent's method2() Parent's method1()"
Prints "Parent's method2() Child's method1()"
Correct Answer:
"Prints "Parent's method2() Parent's method1()"" is correct !

1) this is what the Child class really looks like on the inside - it contains 3 methods:
// from the Parent - but INACCESSIBLE to reference types of type Child
private void method1() {
System.out.println("Parent's method1()");
}
// new method for Child class
public void method1() {
System.out.println("Child's method1()");
}
// inherited from Parent
public void method2() {
System.out.println("Parent's method2()");
method1();
}
so, when p.method2() is exec, we are actually going to run the instance method from within the Child class which happens to display "("Parent's method2()" because we inherited it and did not change it!
next, from within our inherited method, we call method1() - BUT REMEMBER, we are still executing with reference type p SO the inherited "private" method1() is now ACCESSIBLE from within the Child class and we get the output of that method.
NOTE: we never actually ran ANY methods from the Parent class, it just looks that way cause Child's methods still say "Parent's ..." - it's an illusion!
CONCLUSION - p.methodx() calls are always calling instance methods in this scenario and so we would expect to be running the methods in the subclass - IF we can gain ACCESS to the mthods within.
I always forget the distinctions between inheriting all members of superclass and whether or not they are ACCESSIBLE to the subclass!
Hope this helps - somebody let me know if I am all mixed up!
[ November 18, 2002: Message edited by: david eberhardt ]
david eberhardt
Ranch Hand

Joined: Jul 02, 2002
Posts: 158
I had a wild thought -
using :


I compiled Child.java and got 2 class files:
Parent.class
Child.class
before running c>java Child, I deleted the Parent.class file from the same directory.
So anything produced had to be from within the Child.class file - and this confirmed what I explained in the previous post, that all 3 methods were in the Child class.
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
Hello David.
I did what you said. I got a NoClassDefFoundError.
The private method1 is really defined in Parent. You can check that with "javap -c Parent" or "javap Child".
For resolving the method invokation "method1()" within Parent.method2() from JLS :

15.11.1 Compile-Time Step 1: Determine Class or Interface to Search:
# If the form is MethodName, then there are three subcases:
* If it is a simple name, that is, just an Identifier, then the name of the method is the Identifier and the class or interface to search is the one whose declaration contains the method invocation.

That means we have to search Parent class...

15.11.2.1 Find Methods that are Applicable and Accessible
The class or interface determined by the process described in �15.11.1 is searched for all method declarations applicable to this method invocation; method definitions inherited from superclasses and superinterfaces are included in this search.

Yes there is such applicable method declaration in Parent class...

The following compile-time information is then associated with the method invocation for use at run time:
* The invocation mode, computed as follows:
o Otherwise, if the compile-time declaration has the private modifier, then the invocation mode is nonvirtual.

Now we now that subclass will not be searched for a method overriding to a private method:

15.11.4.1 Compute Target Reference (If Necessary)
o If the MethodName is a simple name, that is, just an Identifier, then there are two subcases:
+ If the invocation mode is static, then there is no target reference.
+ Otherwise, the target reference is the value of this.

That is you can imagine that "method1()" was written as "this.method1()"

15.11.4.4 Locate Method to Invoke
The strategy for method lookup depends on the invocation mode.
If the invocation mode is nonvirtual, overriding is not allowed. Method m of class T is the one to be invoked.

The method1() in Parent will be invoked.
Summing up: if you see an invokation like "method()" within an instance method looks for matching methods in the class containing that method, or its supertypes. If one is found, and is private no overriding is allowed. The same happens if the found method is static or final.
Given that within an instance method the invokation "method()1" is equivalent to "this.method1()", the point when deciding which code a method invokation will execute, is to realize that we must search the class that is the compile of the reference on which the invokation is made or one of its supertypes. Then we must decide if the method found is accessible and overridable.
Examples:
this.method1();---> the compile type of this is the class where this occurs, that is Parent
anInstance.method();---> the compile type of anInstance must be searched for matching declared or inherited method() declarations.
MyClass.method()---> MyClass must be searched for matching declared or inherited method() declarations.
If not a matching method is found a compiler error is produced: try commenting out the declaration of method1() in Parent.
[ November 18, 2002: Message edited by: Jose Botella ]

SCJP2. Please Indent your code using UBB Code
david eberhardt
Ranch Hand

Joined: Jul 02, 2002
Posts: 158
Jose -
ooops - you are absolutely correct.
I just ran it again, after deleting the Parent.class and got same runtime errors as you.
Thank you very much for the detailed walk thru the applicable JLS sections ... I will need to spend some time digesting all that!
Thank you very much.
[ November 18, 2002: Message edited by: david eberhardt ]
david eberhardt
Ranch Hand

Joined: Jul 02, 2002
Posts: 158
Jose
It would appear that it would be possible to reveal or alter private data if one doesn't code very carefully because of this?

[ November 18, 2002: Message edited by: david eberhardt ]
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
private members should not be accessed by public methods
david eberhardt
Ranch Hand

Joined: Jul 02, 2002
Posts: 158
Originally posted by Jose Botella:
private members should not be accessed by public methods

I'm a little confused by that statement.
The example I most recetnly posted is a variation on the original example which started this thread and I am demonstrating that the Parent's public method2() call TO private method1() allows the Child class to access the private method (and variable) in the Parent (by virtue of the ref type p being a Parent) ... the private mthod and variable would otherwise be inaccessible to the Child class.
That's all I am trying to show there ...
Otherwise, if you had a new class - say a BankAccount with a private balance variable, you would need to provide some sort of public interface to this class to obtain that info right?
Aren't those getter and setter methods public interfaces to such a class?
david eberhardt
Ranch Hand

Joined: Jul 02, 2002
Posts: 158
Jose
here's an example (a quick sketch) of what I meant by having public getter or setter available to an outside class to access private data in another:

p.s. this is a little more into design stuf vs programming fundamentals but the topic does revolve around private vs public and access, etc ...
what do you think?
[ November 19, 2002: Message edited by: david eberhardt ]
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
David I agree that the second progrma could be a reason to have a public method to access a private member. But this is so because the public method is done its owns security checks.
With my phrase I meant that is difficult to be surprised if the first program reveals delicate information, given that public methods are calling the private data. Also I was thinking about isolating the private parts of an object, in the sense dictated by encapsulation; not information that after all needs to be known outside the object.
regards.
david eberhardt
Ranch Hand

Joined: Jul 02, 2002
Posts: 158
I understand now.
Thanks very much for all your help.

Whew - I better not blow any questions on the exam after covering this topic so much!
Thanks again.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: About Overridden II (a Mock Question question...)