wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Question on Protected Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Question on Protected" Watch "Question on Protected" New topic
Author

Question on Protected

Sarma Lolla
Ranch Hand

Joined: Oct 21, 2002
Posts: 203
//File 1: c:/abc/def/Q.java:
package def;
public class Q {
protected int protectedVar;
}
//File 2: c:/abc/Tester.java:
import def.Q;
public class Tester extends Q {
Sub sub = new Sub();

public void someMethod() {
sub.protectedVar = 15; // Why not error?
}
}
//File 3: c:/abc/Sub.java:
public class Sub extends Tester {
}
Can any one explain why not compiler is throwing error when I am trying to access a protected var using derived class reference?
I am under the impression that once in a sub class the protected var behaves just a like a private var and thus the classes derived from this class shouldn't be able to access the protected var.
[ March 12, 2003: Message edited by: Sarma Lolla ]
Jasper Vader
Ranch Hand

Joined: Jun 10, 2002
Posts: 57
maybe it would be a runtime error if you tried calling the offending method?


giddee up
Sarma Lolla
Ranch Hand

Joined: Oct 21, 2002
Posts: 203
The code given above works just fine both compile time and runtime
Bryan Yu
Greenhorn

Joined: Aug 08, 2002
Posts: 4
protectedVar is inherited by Sub....
and a protected modifier isn't as restrictive as private... so Sub has access to it...
Jasper Vader
Ranch Hand

Joined: Jun 10, 2002
Posts: 57
i think what Sarma is wondering about is whether the protected member becomes private when inherited once down the line.
Tausif Khanooni
Ranch Hand

Joined: Nov 14, 2002
Posts: 107
I think it is because Classes "Tester" and "Sub" are in default package. If these classes will be put up in some different package then it will not compile.
m i right?


"Walking on water and building IT Architecture from <br />specification are easy if and only if both are frozen"
Sarma Lolla
Ranch Hand

Joined: Oct 21, 2002
Posts: 203
Jasper,
Thanks for understanding the question and putting all my concerns in to one line.
Tausif Khanooni ,
The classes Tester and Sub are not in default package. They are in a different package than the Super class.
Also Please notethat default package has no significance other than you just explicitly didn't give any name to it.
boyet silverio
Ranch Hand

Joined: Aug 28, 2002
Posts: 173
hello Sarma,
Protected members of a class can be accessed by other classes in the same package
Tester is found in the same package as Sub. So Tester can access Sub's protected members including the protected members Sub has inherited. 'protectedVar' was inherited by Sub from Tester (from Q).
"... protected var behaves like a private var..." if the class accessing the protected var (of another class) is found in another package and this class is not a subclass of the class owning the protected var.
hope this helps.
boyet silverio
Ranch Hand

Joined: Aug 28, 2002
Posts: 173
ok! just found the quote i was looking for which may tie up the things said in the earlier post:
"Protected members are accessible in the package containing this class, and by all subclasses of this class in any package where this class is visible." (Mughal).
Archana Annamaneni
Ranch Hand

Joined: Jan 29, 2003
Posts: 147
Original post
//File 1: c:/abc/def/Q.java:
package def;
public class Q {
protected int protectedVar;
}
//File 2: c:/abc/Tester.java:
import def.Q;
public class Tester extends Q {
Sub sub = new Sub();
public void someMethod() {
sub.protectedVar = 15; Why not error?
}
}
//File 3: c:/abc/Sub.java:
public class Sub extends Tester {
}

Boyet I am still confused , What I tought is , Sub can not see the protectedVar because protectedVar behaves like a privte varible in class Tester(even though they are in the same package) , so cmpiler should give the error when Sub trying to access it.
Can you explain it little further.
Archana
peter greaves
Ranch Hand

Joined: Sep 27, 2002
Posts: 51
i think that extends Q gives Tester access via the protected keyword. from there the var has default (package) access. Sub can see it because it is the same (default) package as Tester.
just a newbie guess.


SJCP 1.2
Pallavi Chakraborty
Ranch Hand

Joined: Jan 18, 2003
Posts: 93
Hi everybody,
I found this quote in Khalid Mughal:
public class Superclass A{
protected int superclassVarA;
protected void superclassMethodA() {};
public class subclassB extends SuperclassA{
//in package B
Superclass objRefA = new SubclassB();
// and so on
It says:
Access to protected members of the superclass(SuperclassA) would also be permitted via any references to subclasses of SubclassB.
Any thoughts ?
Pallavi
Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
One thing for sure is that once Tester inherited protectedVar, its SubClass Sub can no longer access protectedVar in its own class. But why Sub can access it in Tester class is really a puzzle.
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Here is the rule from the JLS:
6.6.2.1 Access to a protected Member
Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C. In addition, if Id denotes an instance field or instance method, then:
If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Here is the explanation for the rule from "The Java Programming Language, 3.5 What Protected Really Means)
�The reason behind the restriction is this: Each subclass inherits the contract of the superclass and expands that contract in some way. Suppose that one subclass, as part of its expanded contract, places constraints on the values of protected members of the superclass. If a different subclass could access the protected members of objects of the first subclass then it could manipulate them in a way that would break the first subclass�s contract -- and this should not be permissible.�
boyet silverio
Ranch Hand

Joined: Aug 28, 2002
Posts: 173
ok! the cat is away so mouse is in rrrrrranch time.

from Archana:
...What I tought is , Sub can not see the protectedVar because protectedVar behaves like a privte varible in class Tester(even though they are in the same package) , so cmpiler should give the error when Sub trying to access it


from Yuan:
One thing for sure is that once Tester inherited protectedVar, its SubClass Sub can no longer access protectedVar in its own class. But why Sub can access it in Tester class is really a puzzle.

to put my earlier posts and the Mughal quotes in another way:

1. 'protected' behaves like private when it comes to aggregation (between two classes found in different packages)

Aggregation refers to when a class makes an object of another class as one of its members. In this case, if the containing class accesses the protected members of the contained class found in another package, error arises.
If Sub was in another package than Tester, and Tester uses Sub's protected methods then error will arise. But they are in the same package so no error. But please ... please continue with the following...
2. but 'protected' behaves like public when it comes to inheritance (whether the inheriting and inherited classes exist in different packages, or are in the same package).
Sub has a 'protectedVar' by inheritance from Tester, in turn from Q. So Sub can use protectedVar (not to be confused if the property being inherited is private). This is where 'protected' behaves like public.
'Protected' is like the middle ground between totally public and totally private. Like a cross breed. It's public in some ways and private in other ways.
mohamed hamdy
Ranch Hand

Joined: Feb 13, 2003
Posts: 72
hi,
i think that saying that protected instances are visible in the same package and in the inherited classes in other packages that it can be referenced by a reference of the orinal class and the derived classes has an additional rule in that these protected instances become a memberes in them.
to increase clarity private instances are also members of any derived classes but they can't be set except by a non private method of the base class.
i tried the following code and it compiles:
public class pri{
private int x;
void amethod(){
pri ob=new pri();
pri.x=5;
}
}
i.e the private member x can be referenced but in by an object but in the same class.
Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
One thing to ask boyet.
To my understanding of your post, you said the Sub class can access the protected protectedVar, is that true? If it is true, could you please tell me why the Jcompiler doesn't agree? If it is not true, could you explain to me why Sub.protectedVar is a valid statement in the original code.
Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
Does anybody try to run the codes and then make some comments? Please don't just make quote of some book! Use JCompiler to discuss it.
mohamed hamdy
Ranch Hand

Joined: Feb 13, 2003
Posts: 72
hi,
i got the cofusion point:
access to protected members of the super class is permitted by a referrence of the subclass, but not by a referrence of its superclass.
boyet silverio
Ranch Hand

Joined: Aug 28, 2002
Posts: 173
hello Yuan,

One thing to ask boyet.
To my understanding of your post, you said the Sub class can access the protected protectedVar, is that true? If it is true, could you please tell me why the Jcompiler doesn't agree? If it is not true, could you explain to me why Sub.protectedVar is a valid statement in the original code.
Does anybody try to run the codes and then make some comments?Please don't just make quote of some book! Use JCompiler to discuss it.

Before i posted my earliest post on this thread, i read the code and thought that the code would run. To confirm i then compiled the code and there was no problem. The code was also run during that time using a main method in another class. In the process, a Runtime Error was encountered in the 3rd line of the Tester.java class: Sub sub = new Sub();
i remedied this and proceeded to run it again (for runtime purposes) because this was NOT the problem Salma was pointing out. i understood that Salma (and others) also remedied that earlier problem because what her question was and what she wanted resolved was
sub.protectedVar = 15; // why no error?.
This was what i (and others) responded to in my subsequent posts which was appended with the "quotes". Quotes are helpful in explaining i think.
By the way i used j2sdk's javac to compile. I am not familiar with the JCompiler you're referring to and why it doesn't agree. As to your other questions ... read my earlier posts again. And the posts of others.
Also, you could probably post the error you are getting so others may also help you with it.
[ March 11, 2003: Message edited by: boyet silverio ]
mohamed hamdy
Ranch Hand

Joined: Feb 13, 2003
Posts: 72
one thing can clarify this pointL:
make the class Sub extends Q (instead of Tester)
,then the line under question in class Tester will not compile.
read the previous posts carefully ,and all thing will become clear.
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
Thanks Marlene for the following:

�The reason behind the restriction is this: Each subclass inherits the contract of the superclass and expands that contract in some way. Suppose that one subclass, as part of its expanded contract, places constraints on the values of protected members of the superclass. If a different subclass could access the protected members of objects of the first subclass then it could manipulate them in a way that would break the first subclass�s contract -- and this should not be permissible.�

Yes, if a subclass could access the protected instance members of an object of the superclass, it could leave the object in an inconsitent state. This situation would break the polymorphism if the object of the subclass were to recieve messages intended for an object of the supertype which does comply with such contraints (in a good health state).
__________________________________________________


I just want to show that the protected access restriction only applies to instance members (static fields are not part of the state of an object) ,and , that while the inheritance of static fields does really imply access to the same field, inherited instance fields are a brand new copy of the field declared in the superclass.
[ March 14, 2003: Message edited by: Thomas Paul ]

SCJP2. Please Indent your code using UBB Code
Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
I think I didn't put my question clearly last time. My question is that why in class Tested, Sub.protectedVar is accessable? And if I try to access Sub.protectedVar in its owner class Sub, why would I get an compiler error?
For example, why the following code does not compile?
//File 1: c:/abc/def/Q.java:
package def;
public class Q {
protected int protectedVar;
}
//File 2: c:/abc/Tester.java:
import def.Q;
public class Tester extends Q {
Sub sub = new Sub();
public void someMethod() {
sub.protectedVar = 15; // Why not error?
}
}
//File 3: c:/abc/Sub.java:
public class Sub extends Tester {
protectedVar = 15; //Error now!
}
mohamed hamdy
Ranch Hand

Joined: Feb 13, 2003
Posts: 72
is it possible to type a statement like this
protectedVar=5;
at the class level (not in a block of code or in abody of a method) i tried it but the compiler expects in this case that protectedVar is a class name which can't resolve.
anyway i tried that in a body of a method and it compiles.
Sarma Lolla
Ranch Hand

Joined: Oct 21, 2002
Posts: 203
protectedVar=5;

Are you not missing the data type here?
sharana sharana
Greenhorn

Joined: Mar 14, 2003
Posts: 24
//File 1: c:/abc/def/Q.java:
package def;
public class Q {
protected int protectedVar;
}

//File 2: c:/abc/Tester.java:
import def.Q;
public class Tester extends Q {
Sub sub = new Sub();
public void someMethod() {
sub.protectedVar = 15; // Why not error?
}
}

public class Sub extends Tester {


}
pONT(1):
HI all we know that of a protected members of a superclass is accessbile even outside the package in which the class is declared.
Question is that class visible out side the package ???
since Q is a public class its visible in every package.so its protectedVar is accessible

remember also that NO book has said that protected member becomes private when its get inherited!!!
so even if there is one more depth of inheritance still protectedVar member is inherited and accessible unless otherwise Hidden..

Point(2)
every protected member can be accessible in their subclasses either as
Superclass's Object.Member OR as just by "simple membername" IF IT IS NOT SHADOWED BY SUBCLASS.

/* to test that we can write the Tester.Java as follows
import def.Q;
public class Tester extends Q {
public void someMethod() {
System.out.println(" printing from Tester class "+(protectedVar = 15));

}

public static void main(String[] args) {
Tester t = new Tester();
System.out.println(" Pritning it as superclass.member"+(t.protectedVar=17); // Why not error?
t.someMethod();



}

}
*/
technically speaking FROM above explanation its clear that ,
from a compiler point of View declaring a Object of Sub and then accessing its inherited member protectedVar is nothing wrong so compiler says
" sub.protectedVar = 15; " to OK.
BUT WHEN U try to Execute a above program Java.lang.Stackoverflow error comes
so program wont execute


sharana
mohamed hamdy
Ranch Hand

Joined: Feb 13, 2003
Posts: 72
why this exception is thrown?
boyet silverio
Ranch Hand

Joined: Aug 28, 2002
Posts: 173
here's the remedy. Try separating the declaration and initialization of sub like the ff and the stack over flow error goes away.

[ March 14, 2003: Message edited by: boyet silverio ]
Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
Did a little more tests. Things seem quite interesting to me.
1. Any level of inheritance is fine to access a protected varible, so both Tester and Sub have access to protectedVar.
2. According to Kathy and Bert's book(Pg 80): "Once the subclass-outside-the-package inherits the protected membber, that member(as inherited by the subclass) becomes private to any code outside the subclass." Seems this is not true in our example. protectedVar is inherited by Sub, however in class Tester, we can still access it! I find this only happens because Tester is the superclass of Sub. A simple test is to let Sub extends def.Q directly, then the class Tester will not compile.
SO I guess this is exception that the superclass of a subclass can also access the protected varible inherited by the subclass.
sharana sharana
Greenhorn

Joined: Mar 14, 2003
Posts: 24
the java.lang.Stackoverflow Exception is thrown at runtime becuz the way aggregation is been used there !!!
this is pretty clear if we look at how the class gets loaded , prepared and linked..
in the following code
//File 1: c:/abc/def/Q.java:
package def;
public class Q {
protected int protectedVar;
}

//File 2: c:/abc/Tester.java:
import def.Q;
public class Tester extends Q {
Sub sub = new Sub();
public void someMethod() {
sub.protectedVar = 15; // Why not error?
}
}

public class Sub extends Tester {


}
in the above class defintions we c inheritance heirarchy as def.Q <-- Tester <-- sub
when objects gets constructed first classes gets loaded , static members gets intialized if any , then constructors are invoked and if constructor gets executed successfully then instance variables are initialized to their defualt values.
so in above heirarchy nothing is wrong when Q gets constructed , but when Tester and sub are classes are circularly referncing each other
HERE IS THE PROBLEM
when Tester() constructor finished it starts initializing member variables in this case " Sub sub = new Sub(); " gets called , at this Point sub is not yet constructed , so if Sub needs to be constructed then its superclass constructor must successfully gets constructed and initialized ..which does not happen in this case sooo each start referencing one another Hence the StackOverFlow Exception occurs during Runtime.
hope this explanation Helps Guys
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Question on Protected