wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Possible error in K&B book (resolved - no error) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Possible error in K&B book (resolved - no error)" Watch "Possible error in K&B book (resolved - no error)" New topic
Author

Possible error in K&B book (resolved - no error)

Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
I've not seen this possible error in the "official" errata list.

Extracted from K&B book, page 36:


...when a subclass-outside-the-package inherits a protected member, the member is essentially private inside the subclass, such that only the subclass and its subclasses can access it.


As far as I know, the private modifier applied to a member means (among other things) that the member cannot be inherited. If the protected member becomes private, how can be accessed by subclasses of the subclass?

Please, correct me if I'm wrong.

(Topic title modified to be consistent with conclusion)
[ July 26, 2006: Message edited by: Barry Gaunt ]

Preparing SCJP 1.5
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
Please, correct me if I'm wrong.


Yes you are wrong.

Run this code..

1) File
com1.Super.java



2)
com2.Sub.java file (This file contain two classes Sub and AnyClass)



Here AnyClass is in the same package as Sub1. You will get compilation error at bold line.

Sub class gets i from Super class even they are in different package because field is protected.

So Sub class now has a field i. Now what will be accessiblity of i in Sub class? If i is not becoming private in Sub, then AnyClass can easily access i because its in same package. AnyClass can access i only when it extend either Sub or Super.


Naseem
[ July 25, 2006: Message edited by: Naseem Khan ]

Asking Smart Questions FAQ - How To Put Your Code In Code Tags
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
Naseem, I appreciate your comments, but I don't see what they have to do with the discussion.

What I say is that, according to K&B book, a protected member becomes private in a subclass outside the package where the protected member was declared. It means that, if we extend the subclass that inherits the protected member, any class that extends such subclass should not be able to access the protected member.

See the following example:



Line 1 should give us a compilation error, since "i" becomes private in Sub class, so it's not visible for Test class. If this is true (and it seems it is when running the previous example), the sentence in the K&B book should read:


..when a subclass-outside-the-package inherits a protected member, the member is essentially private inside the subclass, such that only the subclass can access it.


Notice that the text "and its subclasses" has been removed from the sentence.
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
Of course, I missed the "import A.*;" statement, that's why it failed at compile time. Sorry!!! And even including the import statement, I still had to fix file B/Test.java. See the fixed code:



Now that I've fixed the source code file... it works! That means, hence, that protected members do not become private in subclasses outside the package where they are declared!!! Which is still an errata, isn't it?

Now I am even more confused!
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
No its not an errata..

I think you are getting the point what I am trying to say.

Originally posted by Jeronimo Sanchez ...when a subclass-outside-the-package inherits a protected member, the member is essentially private inside the subclass, such that only the subclass and its subclasses can access it.


Do very small test. Extend AnyClass with Sub. What is your output in that case. You won't get any compilation error at the SOP line in that case. WHY? because of subclass of Sub can access it here AnyClass.

Actually what author is tying to say that subclass can access protected feature plus its subclasses.

Suppose GrandParent has protected variable i. Parent can access it as Parent extend GrandParent. Child extending Parent can also access it even its not directly extending GrandParent class. Its subclasses can access it means subclasses of Parent can also access it like Child.

Cheers

Naseem
[ July 25, 2006: Message edited by: Naseem Khan ]
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
Yes, Naseem, you are right, I realized that after I fixed my own sample code. Now it's clear to me that children classes of the subclass also inherits the protected member, and thus they can see it. Then, why does the author write "...the (protected) member is essentially private inside the subclass"?

According to our sample codes, protected member can be accessed by the subclass outside the package, and all its subclasses. But if the protected member would have become private (as the author states), then it could not have been seen by grandchildren classes. Isn't it?

So, as far as I know, I still think there's an errata, not where I originally thought, but in saying that that protected members become private in subclasses outside the package where they are declared. That's not true, unless the concept of private members I have is wrong.
[ July 25, 2006: Message edited by: Jeronimo Sanchez ]
Kevin Crays
Ranch Hand

Joined: Apr 26, 2006
Posts: 41
Originally posted by Jeronimo Sanchez:

Now that I've fixed the source code file... it works! That means, hence, that protected members do not become private in subclasses outside the package where they are declared!!! Which is still an errata, isn't it?

Now I am even more confused! [/QB]


Jeronimo, I'm not sure if your question has been answered or not, but I'm going to give it a shot without going to code.

Basically what K&B is saying is that if you have a class Parent in a package called Guardian. And a subclass named Child in package called Dependents, Child can access a protected field in Parent through inheritance.

However, another Class in package Dependents that is not a subclass of the class Child cannot access the protected fields inherited from Guardian.

To all non subclasses in Package child, the protected fields that Child inherited from Parent are essentially private.

That's how I understand it. I hope that helps.


We're binary code: a one and a zero<br />You wanted violins and you got Nero
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
Then, why does the author write "...the (protected) member is essentially private inside the subclass"?


Lets take one of your code. I have modified your code to illustrate the point.

// File A/Super.java



// File B/Test.java



Sub can access i even if its in different package. TRUE

Can Test be able to access i. NO. You will get compilation error at line 1 even you have imported A.*. Why? You are saying i is not private in Sub class. It means its either of package accessibility or protected or public. If its of default, or protected or public, then Test can also access i as both classes are in same package. That i gets private in subclass of Super and all its subclasses.

I think you are just replying without even running my code. The errata which you have mentioned, I replied it in my first post. Its not an errata at all.


Naseem
[ July 25, 2006: Message edited by: Naseem Khan ]
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
To Naseem:

Of course Test cannot access "i" in your example. It is protected, and is not extending neither Sub nor Super!!! This is not the point.

To see what I mean, please, check this (fixed) example:



Please, note that we need the public method "go" in order to access the protected non-static member "i".

This example compiles and run perfectly well, which demonstrates what you (and now I) know about the private member: that it can be accessed from subclasses. But then, why does the author that protected members become private in subclasses outside the package? That's the point!!!


To Kevin:

Thanks for your explanation. I see your point, but it makes no sense to say that a member is private for non subclasses, since for non subclasses it doesn't really matter if a class member is protected or private: they cannot access the members in both cases.

Private only differs from protected regarding inheritance: meanwhile protected allows the member to be access through inheritance, private does not. And Naseem and I have demonstrated that protected members got inherited to grandchildren classes outside its package. So it cannot become private. So there's an errata in the book.

Why is so difficult to understand. Am I missing something?
[ July 25, 2006: Message edited by: Jeronimo Sanchez ]
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
Originally posted by Jeronimo Sanchez To Naseem:

Of course Test cannot access "i" in your example. It is protected,


Its not protected at all in Sub class. It becomes private in Sub class. If you redefine same field i in Sub class as protected, then i becomes protected in Sub class.

Naseem
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
It IS protected. I'm afraid you have a wrong concept of the private access control modifier. If "i" were private in Sub, then class Test could not access "i" throught inheritance. And the fact is that Test CAN access "i" through inheritance: just run my (fixed) sample source code to check it.
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
You said it is protected in Sub class. If it is protected in Sub class, then all classes in the same package will access it.

I am giving you a simple code. Declare two classes in the same package, Suppose Test1 and Test2.

Test1{
protected int i=9;
}
Test2{
public static void main(String args[]){
System.out.println(new Test1().i); // line 1
}
}

A per your post, line 1 should be compilation error at line 1 because i is protected in Test1.

Naseem
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23

Test1{
protected int i=9;
}
Test2{
public static void main(String args[]){
System.out.println(new Test1().i); // line 1
}
}


Naseem, I'm talking about a class that extends another class in the same package, which in turn extends a third class in a different package.

Your Test2 class does not even extend Test1. And of course, Test2 cannot access "i" in Test1 because "i" is protected. And even if it were private, Test2 still couldn't access "i". This is clear, you are right and I have no problem with this. Again, this is not the point.

I'm starting think that you are not reading all my posts, because your example has nothing to do with what I'm trying to demonstrate.
Kevin Crays
Ranch Hand

Joined: Apr 26, 2006
Posts: 41
Originally posted by Jeronimo Sanchez:
To Naseem:


To Kevin:

Thanks for your explanation. I see your point, but it makes no sense to say that a member is private for non subclasses, since for non subclasses it doesn't really matter if a class member is protected or private: they cannot access the members in both cases.

Private only differs from protected regarding inheritance: meanwhile protected allows the member to be access through inheritance, private does not. And Naseem and I have demonstrated that protected members got inherited to grandchildren classes outside its package. So it cannot become private. So there's an errata in the book.

Why is so difficult to understand. Am I missing something?

[ July 25, 2006: Message edited by: Jeronimo Sanchez ]


The reason they said it is because if in my example the Guardian package had a class Stepfather, which is not a subclass of Parent, it could access the protected field.

As such, one might think that a class in Dependent could access the proteced field that Child inherited. They wanted to remove any ambiguity (which clearly didn't work for you )

Hope that clears it up...if not, I'll check back later.

Kevin
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
Well I think Mr. Bert can better understand you or it could be an errata.

Now I'll lean back and let someone else have the driving seat. Any takers?

Naseem
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
I think the main point of confusion here is in what the levels of access mean.

When we say a variable is protected, we mean that that variable is accessible within that class, within the package containing the class, and within any subclass.

When a variable is declared without an access control modifier, it is accessible within the class and within the package that contains the class.

When a variable is declared private, it can only be accessed within the class.

The situation that the passage is referring to is that a class A in package p is a direct superclass to class B in package q. If A defines a protected member, i, then i is inherited by B.

However, you cannot say that i has protected access in B because that would imply that i could be accessed from other classes in package q that did not extend A directly or indirectly. Also you can't say that i has default access in B because that would imply that other classes in package q that did not extend A directly or indirectly could access i.

The only thing you can say is that B and any subclass of B will inherit i.

So that's the reason for the careful wording in the book.

"Essentially" private in this case does not mean it has private access in B. It can be accessed within B and any subclass of B.

(When I say accessed here, I mean unqualified access in the subclass. Even though B is a subclass of A, if you define an instance of A inside of B, you cannot access that instance's copy of i inside the class B.)
Neelesh Bodas
Ranch Hand

Joined: Jul 20, 2006
Posts: 107
Hi, Jeronimo

Please see the first sentence of second paragraph on page 36 :

No! Once the subclass-outside-the package inherits the protected member, that member (as inherited by the subclass) becomes private to any code outside the subclass, with the exception of subclasses of the subclass.


So the author intends to use the word private not as the access modifier, but as a general term to explain that the code outside the said classes cannot access it.
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
Thanks Keith/Neelesh. Now it's crystal clear!!!

I thought K&B meant private access control modifier, but they definitively didn't. My blame!!

[ July 25, 2006: Message edited by: Jeronimo Sanchez ]
[ July 25, 2006: Message edited by: Jeronimo Sanchez ]
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
Does this mean that we have found a fifth access control level?

I mean, it seems that a protected member in class A that is inherited by class B in another package, has a very special and specific access control level that is not private, nor protected not default (not public, of course).

What do you think?
Kevin Crays
Ranch Hand

Joined: Apr 26, 2006
Posts: 41
No. Protected only allows subclasses and classes that are in the declaring classes package to access it. Those rights don't transfer to the subclass's package.
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Let me give my take on this (I have not read all the previous posts in detail). In the code below I use a static variable to keep things simple.



Look at class E. Even though E and C are in the same package, and the secret in C as inherited from A is protected, E cannot access the secret in C. It's as if secret is private in C from E's point of view.
[ July 25, 2006: Message edited by: Barry Gaunt ]

Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
Getting someone to think and try something out is much more useful than just telling them the answer.
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
You are right, Barry!!!

After some posts (perhaps too many ), I finally realized what K&B tried to explain. Now it's clear to me there is no bug in the book. And your sample code is quite educative, really! (as always)

My last thought regarding this subject is: if the secret does not become protected in class C (since class E cannot access it), nor private (since class D inherits the secret)... is it possible to say we have a fifth access control level, yet very specific?
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Originally posted by Jeronimo Sanchez:

My last thought regarding this subject is: if the secret does not become protected in class C (since class E cannot access it), nor private (since class D inherits the secret)... is it possible to say we have a fifth access control level, yet very specific?


No, I don't think so. Where is secret? It is not really in C, it's still in A as a protected member. E is in another package and not a subclass of A. So it's not visible as in the normal protected access definition.

It would be good to do the exercise with a nonstatic protected member to see whether my argument is still valid.
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
Barry, your are completely right. I run the same exercise modified to use a nonstatic secret, and the result is exactly the same, as you predicted.

Thanks all that have posted to this thread. Not only I learnt to correctly interpret the authors of the K&B book, but also it indirectly helped me to burn in my brain the control access modifiers (even the hard one: protected) ;-)

Hope I can help you the same way very soon!!!
Bert Bates
author
Sheriff

Joined: Oct 14, 2002
Posts: 8803
    
    5
phew!


Spot false dilemmas now, ask me how!
(If you're not on the edge, you're taking up too much room.)
Bert Bates
author
Sheriff

Joined: Oct 14, 2002
Posts: 8803
    
    5
phew!
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Yep, saved your bacon again Bert. I'll edit the topic title now.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: Possible error in K&B book (resolved - no error)
 
Similar Threads
A fuzzy question...
doubt
Protected access modifier
Doubt in K&B SCJP 5: protected access
confusion regarding protected keyword