Get your CodeRanch badge!*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Why doesn't polymorphism determine the output in this case? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Why doesn Watch "Why doesn New topic
Author

Why doesn't polymorphism determine the output in this case?

Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Why doesn't a polymorphic call to doThis() get past the compiler in this instance? Compiler output is in RED below. Does this mean that it isn't possible to override a protected superclass method when the overriding method is in another package?






C:\Documents and Settings\Harry Henriques>javac -cp . pkgb/clasB.java
pkgb\clasB.java:9: doThis() has protected access in pkga.clasA
ca.doThis();
^
1 error
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18104
    
  39

Harry Henriques wrote:Does this mean that it isn't possible to override a protected superclass method when the overriding method is in another package?


Of course, it is possible to override protected methods. The methods of the subclass can access it protected superclass, via a call with the super.doThis() construct.

But... that is not what your example is doing. You example is merely dereferencing a instance, to call a method. This is no different than dereferencing any other instance to call a method. And in this case, to call a protected method, your class must be in the same package, and if it is not...

Java Language Specification wrote:6.6.2 Details on protected Access
A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.


As far as the compiler is concern, your clasB is trying to directly access a clasA instance, which doesn't meet this requirement (it is an instance that it is "responsible for the implementation of that object", but the compiler doesn't know that).

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Henry,

I'm not sure I understand you. Please let me make the following observations: (1) clasA has a method with the following signature protected void doThis() (2) clasB has a method with the following signature public void doThis() (3) The access modifier on the overriding subclass method is less restrictive. (4) clasB extends clasA (5) if clasB and clasA were in the same package, then the output of this code would be Subclass Method.

Instead, I get a compiler error when compiling this code.

Henry Wong wrote:Of course, it is possible to override protected methods. The methods of the subclass can access it protected superclass, via a call with the super.doThis() construct.


Accessing the doThis() method in the superclass from the subclass using super.doThis() is not using the overriding mechanism. It is strictly using Inheritance, not Polymorphism.


Java Language Specification wrote:
6.6.2 Details on protected Access
A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.


I guess this answers the question. Polymorphism isn't effectual across disparate packages (even in the case of two classes that have an Inheritance relationship).

Do you agree, Henry?

-Harry


a alph
Ranch Hand

Joined: Nov 18, 2008
Posts: 36
Hi

I understand that the protected members can be accessed only through inheritance.

Can you please explain to me how to access the protected method by using super.doThis() ?
When I insert the super.doThis() in the following code, it says "non static variabe super cannot be referenced from a static context".








Maybe I inserted in the wrong line??

Thanks.
Alex Serna
Ranch Hand

Joined: Sep 18, 2009
Posts: 58

If you invoke from main you are saying doThis() is static which it isn't. You can't invoke ClassA's doThis() by reference outside ClassA. You can inherit it in classB and you can use it within ClassB's instance methods. But if you override it and mark it ass public you can use it again from anywhere you want.
Valentin Ivanov
Ranch Hand

Joined: Nov 20, 2008
Posts: 36

Hi a alph,
did you try to invoke super.doThis() from an instance method and not from main? After all the method is protected and not static protected.
S Ali
Ranch Hand

Joined: Aug 23, 2009
Posts: 129
If a method is overridden but you use a polymorphic (supertype)
reference to refer to the subtype object with the overriding method, the compiler
assumes you’re calling the supertype version of the method. (from K & B)

in this case the superclass method was declared protected which means that it can't be accessed through a reference variable even if you override it with public access the compiler still sees the method interface of the reference variable type. Hope that answers it.


SCJP 6
a alph
Ranch Hand

Joined: Nov 18, 2008
Posts: 36

Valentin Ivanov wrote:
did you try to invoke super.doThis() from an instance method and not from main? After all the method is protected and not static protected.


I tried the following code. But it doesn't print anything. It compiles fine.




Can you please explain why it doesn't print anything??

Thanks..
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18104
    
  39

a alph wrote:
Can you please explain why it doesn't print anything??


Well, here is your main() method. Can you tell us what it does?



Henry
a alph
Ranch Hand

Joined: Nov 18, 2008
Posts: 36
I think, without the main() method, the class can't be run.

And I managed to find the point. I don't know how I missed it.




Thanks guys.
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
K&B wrote: If a method is overridden but you use a polymorphic (supertype)
reference to refer to the subtype object with the overriding method, the compiler
assumes you’re calling the supertype version of the method.

S Ali wrote:
in this case the superclass method was declared protected which means that it can't be accessed through a reference variable even if you override it with public access the compiler still sees the method interface of the reference variable type. Hope that answers it.


The output of the code below is at the end of this post in RED.

In this case, the protected superclass method is referenced by a superclass reference (this is what the compiler sees), but the method with public access in the subclass is invoked polymorphically at runtime. The subclass method with public access overrides the protected superclass method (polymorphically). Both the superclass and the subclass are in the same package (in the same file). This doesn't happen when the protected superclass method is in one package and the public subclass method is in another package. In fact, a compiler error message is generated. Overriding a method is a Polymorphic concept, not an Inheritance concept. Without polymorphism, the concept of overriding a method doesn't make sense.




C:\Documents and Settings\Harry Henriques\pkgb>java clasB
Subclass Method
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
a alph wrote:
Hi

I understand that the protected members can be accessed only through inheritance.

Can you please explain to me how to access the protected method by using super.doThis() ?
When I insert the super.doThis() in the following code, it says "non static variabe super cannot be referenced from a static context".


This is an example of what Henry Wong was talking about. -Harry







C:\Documents and Settings\Harry Henriques>javac -cp . pkgb/clasB.java

C:\Documents and Settings\Harry Henriques>java -cp . pkgb/clasB
Superclass Method
Subclass Method

S Ali
Ranch Hand

Joined: Aug 23, 2009
Posts: 129
The output of the code below is at the end of this post in RED.

In this case, the protected superclass method is referenced by a superclass reference (this is what the compiler sees), but the method with public access in the subclass is invoked polymorphically at runtime. The subclass method with public access overrides the protected superclass method (polymorphically). Both the superclass and the subclass are in the same package (in the same file). This doesn't happen when the protected superclass method is in one package and the public subclass method is in another package. In fact, a compiler error message is generated. Overriding a method is a Polymorphic concept, not an Inheritance concept. Without polymorphism, the concept of overriding a method doesn't make sense.


The subclass method with public access does override the superclass's method at runtime.But only the implementation is overriden ,the method declaration is still seen of the type of the reference variable. Your example worked because protected access inside the same package is just like default, it can be accessed through a reference.

Another example to demonstrate the concept from K&B page 108: If the supertype version
declares a checked exception, but the overriding subtype method does not, the compiler
still thinks you are calling a method that declares an exception and you are required to handle it.
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
S Ali wrote:
The subclass method with public access does override the superclass's method at runtime.But only the implementation is overriden ,the method declaration is still seen of the type of the reference variable. Your example worked because protected access inside the same package is just like default, it can be accessed through a reference.

Another example to demonstrate the concept from K&B page 108: If the supertype version
declares a checked exception, but the overriding subtype method does not, the compiler
still thinks you are calling a method that declares an exception and you are required to handle it.


I don't believe that you are correct. If the subclass method overrides the superclass method, then I wouldn't get a compiler error in my original code (in the original post at the top of this thread). When the superclass method and subclass method are in different packages (directories), the subclass method doesn't override the superclass method. The subclass inherits from the superclass, and that's it.

In my original post, the subclass method implements a less restrictive access than the superclass method (the compiler should be satisfied). In my original post, I implement a correct polymorphic invocation of the doThis() method in the subclass using a superclass reference, but the compiler declares that there is a compiler error. It has nothing to do with the access modifers; the access modifiers are irrelevant although they are appropriate.

I understand your reference to page 108 in K&B. I don't think that it applies to this case. Maybe you should try implementing your suggestion in two separate directories, and see what happens?

-Harry
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18104
    
  39

Harry Henriques wrote:I don't believe that you are correct. If the subclass method overrides the superclass method, then I wouldn't get a compiler error in my original code (in the original post at the top of this thread). When the superclass method and subclass method are in different packages (directories), the subclass method doesn't override the superclass method. The subclass inherits from the superclass, and that's it.



I think you are making incorrect conclusions here. Yes, the compiler is complaining about access rights, but that doesn't mean that the method hasn't been overridden. Or that polymorphism is broken.

For example, if you move the main method to another class. A class that has access rights to the method, say a class in the same package as clasA, then the compiler will allow the call -- and you will see that it is the subclass (clasB) method that is called.

Henry

Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
This works, but I'm not sure that I understand just why it works. Can you explain it further, Henry?

Thanks,
Harry







C:\Documents and Settings\Harry Henriques>javac -cp . pkga/clasA.java

C:\Documents and Settings\Harry Henriques>java -cp . pkga/clasA
Superclass Method
Subclass Method
Salil Vverma
Ranch Hand

Joined: Sep 06, 2009
Posts: 253

Hey Harry,
I believe, you are clear why it is compiling fine.
Now about the explanation of output. The execution starts in the main method so I will focus on the code inside main.\


In the first line, it creates an object of clasB and assigns its reference to ca.
Now about the second line. It calls ca.doThis(). As we know that clasB overrides doThis() method of clasA, ca.doThis() would call the doThis() function of clasB object.

Now inside doThis() function of clasB object. it make a call of super.doThis();. super.doThis(); calls the doThis() function of super class ie doThis(). As we can see doThis() function of classA prints "Superclass Method" so it prints this as a fist line.

And I guess the explanation of second line is pretty clear.

Regards
Salil Verma
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Let me be clear. In the code from the original post at the top of this thread, the compilation failed. In my last post at the bottom of the thread, the compilation didn't fail. The code is my previous post compiled and ran correctly. Why does the overriding mechanism work correctly in the previous code post, but it doesn't work at all in the original post at the top of the thread? Why does compiliation fail in the original post at the top of the thread? Why does compilation pass without error in the previous code post?
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18104
    
  39

Harry Henriques wrote:This works, but I'm not sure that I understand just why it works. Can you explain it further, Henry?


Basically, this case works because you are permitted access. This issue has NOTHING to do with polymorphism, inheritance, etc. etc. The first case doesn't compile because you tried to access a method that you wasn't allowed to access.

You would have gotten the same compile error, if clasB did not subclass from clasA, and you tried to access a protected method of clasA from clasB.

It actually got a bit more complex because clasB did inherit from clasA, but all that seemed to do is confuse the matter. And lead you to somehow conclude that it is polymorphism that is broken, instead of the compiler correctly preventing you from accessing something that you don't have the rights to.

Henry
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
Thanks, Henry. I understand now. The example below is strictly Inheritance where clasB has access rights to the doThis() method in the superclass. -Harry







C:\Documents and Settings\Harry Henriques>javac -cp . pkgb/clasB.java

C:\Documents and Settings\Harry Henriques>java -cp . pkgb/clasB
Superclass Method
Salil Vverma
Ranch Hand

Joined: Sep 06, 2009
Posts: 253

Hi Harry,

The reason behind first code giving the compilation error and second code compiling fine is that compiler checks the accessability of specific method on the basis of reference variable type and the methods

In the second code protected method is in the same class so it the compiler knows that this method is in the same class so can be accessed and does not give the compilation error.
Harry Henriques
Ranch Hand

Joined: Jun 17, 2009
Posts: 206
K&B [surl='http://www.coderanch.com/how-to/java/ScjpFaq' class='api' title='SCJP FAQ wrote:SCJP[/surl] 5 Study Guide pg. 34]
So if the subclass-outside-the-package gets a reference to the superclass (by, for example, creating an instance of the superclass somewhere in the subclass' code), the subclass cannot use the dot operator on the superclass reference to access the protected member. To a subclass-outside-the-package, a protected member might as well be default (or even private), when the subclass is using a reference to the superclass. The subclass can see the protected member only through inheritance.
Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

May be this is a bit later..... but i kind of like to add some thing... 2 things we need to know.

1- When does the polymorphic method gets called?
2- When was the error displayed for the code(compile time or runtime)?


[ SCJP 6.0 - 90% ] , JSP, Servlets and Learning EJB.
Try out the programs using a TextEditor. Textpad - Java 6 api
Salil Vverma
Ranch Hand

Joined: Sep 06, 2009
Posts: 253

- When does the polymorphic method gets called?

Methods are used in a polymorphic way without using x.getx() way. if any function is called in x.functionname() format that is non polymorphic way.

When was the error displayed for the code(compile time or runtime)?

It was compilation error
Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

Well i don't think the first answer is appropriate but well i think the concept is pretty much clear..... the function has many forms and.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why doesn't polymorphism determine the output in this case?
 
Similar Threads
Package Problem...
Please help me to get Java Certification
Enum member variable access
ExamLab 2nd exam 58th
protected static method visibility