File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes question from JQ+ Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "question from JQ+" Watch "question from JQ+" New topic
Author

question from JQ+

Padma Shyam
Greenhorn

Joined: Feb 14, 2002
Posts: 7
Can anyone help me with this code?Thanks in advance.The answer says that though,class B extends A and i is a protected variable,it cannot be accessed from B(thro' B's reference).
Consider following two classes:
//in file A.java
package p1;
public class A
{
protected int i = 10;
public int getI() { return i; }
}
//in file B.java
package p2;
import p1.*;
public class B extends p1.A
{
public void process(A a)
{
a.i = a.i*2;
}
public static void main(String[] args)
{
A a = new B();
B b = new B();
b.process(a);
System.out.println( a.getI() );
}
Padma Shyam
Greenhorn

Joined: Feb 14, 2002
Posts: 7
I am sorry.The answer given is class B cannot access variable i thro' A's reference,since B is not involved in the implementation of A.
Can anybody explain this?
Rob Ross
Bartender

Joined: Jan 07, 2002
Posts: 2205
I'm assuming you're talking about this code:

You should be more specific so more people will understand what you are asking. :roll:
The issue here is access of member 'i' via the a variable, a reference variable of type A.
Now, it's true that this method is a member of class B, which inherits from A, so any method of B is free to access this member i.
However, we are NOT accessing B's inherited version of i, we are accessing some other object's member i, via a reference. That reference is an A reference, and in the current scope of the method processA(), i is not accessible.
A.i is in another class, in another package, and is marked protected, so that processA() is not allowed to access it. If A.i were public, OR if classes A and B were in the same package, then you could access A.i in the processA() method.


Rob
SCJP 1.4
Padma Shyam
Greenhorn

Joined: Feb 14, 2002
Posts: 7
Hi Rob,
Thanks for your quick response.
Isn't it true we can access the 'protected' variable from any subclass of the class even outside the package?
Rob Ross
Bartender

Joined: Jan 07, 2002
Posts: 2205
that's true, but that is NOT what is happening in the method.
You are NOT accessing the i member of B, that is inherited from A in a different package. Rather, you are trying to access a member i of an object of class A, and this follows the normal access rules. Because A.i is protected, and because the reference is made in a class that is in a different package, you cannot access A.i from the method.
Try changing the parameter from an A to a B. If you do that, you will see you no longer get an error. That is because you are now refering to the i member of the B class, and since the method executing is in this class, it can access that member now.
Padma Shyam
Greenhorn

Joined: Feb 14, 2002
Posts: 7
Hi Rob,
Thank you so much.I got it now.
Peter Bugla
Greenhorn

Joined: Feb 12, 2002
Posts: 22
Originally posted by Rob Ross:
Because A.i is protected, and because the reference is made in a class that is in a different package, you cannot access A.i from the method.

Sorry, I don't get it. (protected means: classes from the same package OR subclasses can access it)
I understand, that variables are "chosen" depending on the declaration of the class (A in this case), but I don't understand why this should result in a compiler error "i has protected access in p1.A" (which it does).
As B extends A and our computation takes place in B, we should be able to access protected variables of A.
Can someone explain it in some other way, or give me a pointer to a line in the JLS, where this behavior is explained, please?



Peter Bugla<br />Sun Certified Programmer for Java 2 Platform
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
Peter,
here it is:
6.6.7 Example: protected Fields, Methods, and Constructors


SCJP 5, SCJD, SCBCD, SCWCD, SCDJWS, IBM XML
[Blog] [Blogroll] [My Reviews] My Linked In
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
Let me take a stab at this one by restating the problem a little differently. Look at the following classes:

Now, look at the lines within the method doIt. Line 1 compiles with no problems because we are accessing an inherited element within the class Subclass. This element (the int variable, i) was inherited from the class Superclass. This is perfectly legal.
However, line 2, which looks similar is not legal. In line 2, we're trying to access the member i, of some object of type Superclass. By doing so, we are not accessing the member that was inherited by Subclass. We are trying to access some other variable of some other class in some other package. It makes no difference, in this case, that the class we are implementing inherits from the class that we are passed as a parameter. Can you see why the following is illegal?

Do you see why this code would cause a compiler error? The member numFeet in Dog is inaccessible to the class Cat, which is in another package. The reason this is illegal is the exact same reason that line 2 above is illegal.
The difference between lines 1 and 2 above is what exactly is being accessed. In line 1, we're accessing the inherited variable. In line 2, we are not. Therefore, the normal accessibility rules apply, just as they apply in the Dog and Cat example.
I hope this clears things up for you,
Corey


SCJP Tipline, etc.
Brian Lugo
Ranch Hand

Joined: Nov 10, 2000
Posts: 165
If I code all the classes in the same file/package it works fine:

There are no compile errors and it works fine.
Am I doing something wrong?
Can some one please explain/address this thread in a more subtle way?
Thanks,
Brian
PS - I am not sure if this is a compiler bug, i.e. it does not follow the specification or if specification has a bug in it regarding accessing protected members from a different package.
Does is say specifically anywhere in the JLS "Protected members cannot be accessed properly in a subclass in a different package"?
[ February 18, 2002: Message edited by: Brian Lugo ]
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
Originally posted by Brian Lugo:
If I code all the classes in the same file/package it works fine...

Of course this will work is you place all of the classes within the same package. A protected member is accessible to all classes that are descendents of that class or to any other classes within the package.
Therefore, the member variable i of class A is accessible within class C as long as they are within the same package. If you change the accessibility of i to private or you move A to a different package, you'll get the compiler error back. Tese are the standard accessibility rules for classes in Java.
I think you're getting confused with inheritance. In this case, you're only using inheritance in the line where you have i = i + 1. In the following line, where you have someclassoftypeA.i = someclassoftypeA.i + 1, you are NOT using inheritance. I can't stress this enough. You are not accessing the member that class C inherited from class A. You, therefore, can not access the member i via inheritance accessibility rules. You must follow the standard Java accessibility rules to get at that variable. That's why, when you place the classes in the same package, it works. But, when you place the classes in different packages, it doesn't work.
Make sure you see the difference between i = i + 1 and someclassoftypeA.i = someclassoftypeA.i + 1. What is actually being accessed is very different. In the first one, the variable i is part of class C (it was inherited from class A) but, in the second line, the variable someclassoftypeA.i = someclassoftypeA.i + 1 is not part of class C. Rather, it is part of an object of type A. This is a very significant difference and is the cause for the compiler error.
Does this make sense? What are you still confused on? Perhaps I can try to focus on that.
Corey
P.S.
I do not believe this is a compiler error. As far as I can tell, the compiler is behaving exactly as it should.
[ February 18, 2002: Message edited by: Corey McGlone ]
Brian Lugo
Ranch Hand

Joined: Nov 10, 2000
Posts: 165
Corey,
I understand you, I guess I was unaware (as dumb as it may sound) of this fact:
"A protected member is accessible to all classes that are descendents of that class or to any other classes within the package."
is it true about this :
" any other classes within the package"?
or this is true:
"A protected member is accessible to only classes that are descendents of that class and the descendant class is in the same package"
Brian
PS - Nevermind - I guess I just learned correctly what protected means today ...
[ February 18, 2002: Message edited by: Brian Lugo ]
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
Originally posted by Brian Lugo:
Corey,
I understand you, I guess I was unaware (as dumb as it may sound) of this fact:
"A protected member is accessible to all classes that are descendents of that class or to any other classes within the package."
is it true about this :
" any other classes within the package"?
or this is true:
"A protected member is accessible to only classes that are descendents of that class and the descendant class is in the same package"
Brian

Please review this section of the JLS: 6.6.2 Details on protected Access.
A protected member is accessible to any class within the same package and also to any class outside that package that is a subclass of the class where the member is declared.
Look at the following code:

Questions? Comments? General Confusion?
Corey
Brian Lugo
Ranch Hand

Joined: Nov 10, 2000
Posts: 165
Hi Corey!
Thanks for your patience, I am glad I am a member of JavaRanch.
I always thought "only" the subclass can access the protected members, regardless of which package they are in. I was definitely wrong.
Thanks to every body who contributed on this
thread,
Brian
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
I'm glad this was cleared up for you, Brian. One big difference between C++ and Java is that protected accessibility is actually quite accessible in Java, unlike C++. In C++, protected members can only be accessed by subclasses. Perhaps this is where your confusion was coming from. In Java, the accessibility modifiers, in order from greatest accessibility to least is like this:
1. public
2. protected
3. default / package
4. private
If you have any more questions, don't hesitate to ask.
Corey
Brian Lugo
Ranch Hand

Joined: Nov 10, 2000
Posts: 165
Yes Corey you correctly identified my C++ background .
Peter Bugla
Greenhorn

Joined: Feb 12, 2002
Posts: 22
Thanks Valentin.
JLS:
it cannot access the protected members x and y of its parameter p, because while B (the class in which the references to fields x and y occur) is a subclass of A (the class in which x and y are declared), it is not involved in the implementation of an A (the type of the parameter p).
So here we go again... can anyone clarify what they try to say with "it is not involved in the implementation of A"? Perhaps they have just used some strange meaning of "implementation"?

What I understand is, that the parameter's member variable is not the one inherited from the instance of B, of course.
But that doesn't imply, that B can't access it.
AFAIK the accessibility modifiers don't work on instance level, e.g. if some variable a is private in a class X, which has two instances x1 and x2, x1 can access x2.a and vice versa.
So why should that be different here?
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
Originally posted by Peter Bugla:
Thanks Valentin.
JLS:
it cannot access the protected members x and y of its parameter p, because while B (the class in which the references to fields x and y occur) is a subclass of A (the class in which x and y are declared), it is not involved in the implementation of an A (the type of the parameter p).
So here we go again... can anyone clarify what they try to say with "it is not involved in the implementation of A"? Perhaps they have just used some strange meaning of "implementation"?

What I understand is, that the parameter's member variable is not the one inherited from the instance of B, of course.
But that doesn't imply, that B can't access it.
AFAIK the accessibility modifiers don't work on instance level, e.g. if some variable a is private in a class X, which has two instances x1 and x2, x1 can access x2.a and vice versa.
So why should that be different here?

Take a look at this code:

As you can see, I create a new object of type AccessingPrivateMember on line 1. Yet, in the following few lines (and in the method changeMember), I'm able access the private member i without any problem. This is because I'm in a class that in involved in the implementation of that class. Had o been of some other type, even that of a super class, I would not have been able to access i because it is private. This is what it means to be "involved in the implemenation" of the other class.
Does that make sense? I guess this topic was more confusing that I expected. Let me know if you still have questions.
Corey
Peter Bugla
Greenhorn

Joined: Feb 12, 2002
Posts: 22
Okay ,let me see, if I got it now.
When they talk about "involved in the implementation" they mean involved in the _construction_, right? So if the compiler can't see if the object has been constructed in a section of the subclass, it can't access protected variables?
Concerning the program we started with...


//in file B.java
package p2;
import p1.*;
public class B extends p1.A
{
public void process(A a)
{
a.i = a.i*2;
}
public static void main(String[] args)
{
A a = new B(); // 1
B b = new B(); // 2
b.process(a); // 3
System.out.println( a.getI() );
}

...
Would the line a.i = a.i*2; work if it is in main
after line 1?
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: question from JQ+