• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

access to protected member

 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, All,

I'm working on SCJP and have a question about access to protected member. I hope someone can give me some hint on it.

In one source file, Parent.java, I have:

-------------
package cert;

public class Parent {
protected int i = 3;
}
--------------

In the second file, ChildOutsidePackage.java, I have:

------------
package noncert;

import cert.Parent;

class ChildOutsidePackage extends Parent {
public static void main(String[] args) {
ChildOutsidePackage c = new ChildOutsidePackage();
System.out.println("c.i = " + c.i);

GrandChildOutsidePackage gchild = new GrandChildOutsidePackage();
System.out.println("gchild.i = " + gchild.i);

Neighbor n = new Neighbor();
System.out.println("n.neighborc.i = " + (++n.neighborc.i));
}
}

class GrandChildOutsidePackage extends ChildOutsidePackage { }

class Neighbor {
public ChildOutsidePackage neighborc = new ChildOutsidePackage();
}
--------------------------------------------------------------

Below is the output:

------------------------
build$ javac -d . -classpath . ../ChildOutsidePackage.java
build$ java noncert.ChildOutsidePackage
c.i = 3
gchild.i = 3
n.neighborc.i = 4
------------------------


I understand that ChildOutsidePackage and GrandChildOutsidePackage have access to the protected member i through inheritance. What bothers me is why Neighbor has access to i. Class Neighbor is in a package different from class Parent and it is not its subclass. Isn't the protected member i supposed be invisible to class Neighbor?

I know it is a kind of odd to place an instance of Neighbor inside of the main() of class ChildOutsidePackage. If I move the main() to class Neighbor as follows,

----------------------
package noncert;

import cert.Parent;

class ChildOutsidePackage extends Parent { }

class GrandChildOutsidePackage extends ChildOutsidePackage { }

class Neighbor {
public ChildOutsidePackage neighborc = new ChildOutsidePackage();

public static void main(String[] args) {
ChildOutsidePackage c = new ChildOutsidePackage();
System.out.println("c.i = " + c.i);

GrandChildOutsidePackage gchild = new GrandChildOutsidePackage();
System.out.println("gchild.i = " + gchild.i);

Neighbor n = new Neighbor();
System.out.println("n.neighborc.i = " + n.neighborc.i);
}
}
----------------------

The program can't compile, which is expected:

----------------------
build$ javac -d . -classpath . ../ChildOutsidePackage.java
../ChildOutsidePackage.java:28: i has protected access in cert.Parent
System.out.println("c.i = " + c.i);
^
../ChildOutsidePackage.java:31: i has protected access in cert.Parent
System.out.println("gchild.i = " + gchild.i);
^
../ChildOutsidePackage.java:34: i has protected access in cert.Parent
System.out.println("n.neighborc.i = " + n.neighborc.i);
^
3 errors
-----------------------

Could anyone give some explanation? Thanks in advance.
 
Ranch Hand
Posts: 331
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Marvin,


The neighbour class doesn't have direct access to 'i'... It has a childOutsidePackage within it and it accesses 'i' only through an object of childOutsidePackage....

Had you used, n.i instead of n.neighborc.i, the compiler would've shown the access-violation error...

Regards,
Vishwa
[ June 16, 2008: Message edited by: Vishwanath Murthi ]
 
Sheriff
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"Marvin," please check your private messages by clicking on My Private Messages. Thanks!
[ June 16, 2008: Message edited by: marc weber ]
 
Marvin Lew
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Vishwanath,

Thank you for the reply. I think I understand what you wrote: n.i is wrong since i is not a member of class Neighbor.

What I was trying to do in class Neighbor is to access the member i using reference, as described in Sierra's SCJP book. In this case, I included a reference, neighborc, to an instance of class ChildOutsidePackage and tried to access member i using that reference. According to what the book said, protected member inherited in a subclass that is not in the same package of the superclass is private to other classes except to the subclasses of that subclass. However, as I mentioned in my previous post, it worked if the code is included in the main() of class ChildOutsidePackage but failed if included in main() of class Neighbor. It seems there is something I missed or I just read the book wrong. Any suggestion?
 
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dear Marvin,

To my understanding, if you see the Parent class was not in same package
as in noncert, still the code ran and compiled fine. Why it was
getting accessed in the childoutside package was, childoutside package
was extending parent. So it can access the member. i.

By definition of protected variables

a)Having a package level access
b)Outside package only available through Inheritance

So your first version of the code was satisfying the conditions above.
So it ran fine. Because, even outside the package, Child was extending
class parent, so protected member was accessible.

Second scenario

But when the main method was moved to neighbor class it is not doing anything like

a) Not extending Parent
b) Parent is not in the same package as non-cert

So, all above conditions became false due to Clause 1 and 2.

The member will become 'private' to the class Neighbor, so it will give
you the visibility error. Try declaring another protected member say in
child class for example,

protected int a = 2 ;

Try accessing in neighbor the cod will compile fine.

I hope i have tried to clarify your above doubt. Your second scenario
is violating both of the above conditions.

Hope this helps.

Best Regards,
Ben
 
Marvin Lew
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Ben,

Thanks for the explanation. Yes, I do see why it is possible to access the protected member i from the class ChildOutsidePackage in the first scenario. But how about the last println in the main() method in the first scenario?

System.out.println("n.neighborc.i = " + (++n.neighborc.i));

Here i is accessed through a reference to an instance of class ChildOutsidePackage, i.e., the variable neighborc. And the variable neighborc is a member of the class Neighbor. Since the class Neighbor is not a subclass of the class Parent and it is not in the same package of Parent, it is not supposed to be able to "see" the protected member i. But the output shows that it does. That's what confuses me.
 
Ben Zaidi
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dear Marvin,
To my understanding, in case 1, if you see that, ChildOutSidePackage
is extending Parent. Correct? There you declare an object of Neighbor
which is a reference in the ChildOutSidePackage which in turns define,
a protected referece of Childoutside package means composition. But
neighbor is coming in scope of ChildOutsidePackage, so such a reference
can access the protected member of the class it is not directly extending
and where the other class is not in the same package also. It is accessing
the protected member 'i' through reference of ChildOutSidePackage which
is in this scope also extending Parent. So i ll evaluate the following
rules from the behavior above

If a class is extending a class. Parent class and child class both
exist in different packages. Now another class, which is not extending
the parent but contains itself a reference of the child class and that
class instances is instantiated from the subclass, then through this
protected reference of the child class, we can access the protected
member of the Parent class. But if that class reference is not in the
scope of the child class, then it can never access the protected member
of the parent, as protected member will become private.

As see Neighbor reference was in the Childscope package, you can think
of this as a local reference in the child class and basically main is the
method of Child class from where you are accessing the protected member.
Actually another point can be that, this memeber is actually getting
accessed through the method in the childclass which is extending Parent.

In second scenario check this, main is the method of Neighbor class not
child class.

Another reason can be, that actually this protected member was being
accessed through the method of the ChildClass and in second case if
we reverse the logic, it won't work.

Hope this clarifies your confusion a bit. I will welcome, if some other
inputs will come regarding this question.

Ben
 
Marvin Lew
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Ben,

So what you meant is that the place where an instance of a class is created matters. In light of what you said, I tried another program:

class A {
private int privateMember = 1;

public static void main(String[] args){
B b = new B();
System.out.println("b.a.privateMember = " + ++b.a.privateMember);
}
}


class B {
A a;

B() {
a = new A();
}

void func1() {
//System.out.println("" + ++a.privateMember);
}
}


Class B can access a private member of class A as long as an instance of class B is instantiated in the scope of class A. On the other hand, if we uncomment the method func1(), the program will not compile.

Thank you so much for pointing that out. It may seem quite silly but got me confused in the beginning. And I don't recall seeing any books or materials discussing such an issue.
 
Ben Zaidi
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I tried figuring out a reason, because such an issue i didn't come across
also, but seems like, the reasoning i provided above seems to fit the hole
perfectly. I didn't know even private members will be accessed this way.
I will try to figure out more technical technical explanation of this
problem and will come back.

But seems like, the above reasoning is proven correct. Additionally
if we notice oenthing more, we have declared B's object in class A
through composition, which means B is the member of class A, and member
can access the private/protected members, within the scope of where
it was instantiated. I ll come back with more technical reasons. Lemme
think.

Ben

Regards,
Ben
 
Ben Zaidi
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Okay Marvin, i discussed with my senior also, same question.
He said the same, logical reason is this, no matter how you
are accessing the private/protected member, as long as it is
in the scope of class. And in both cases, B was instantiated
within the scope of class A. In nieghbor example, that protected
member was visible to child, as Nieghbor was instantiated within
scope of Child, so that sums up. Thanks for a good discussion about
this, really brought certain new clarities. Keep rocking.
Ben
 
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Does it have to do with the instantiation within the scope, or the mere access to the private/protected member being in the scope?
 
Ben Zaidi
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is actually related to access the private/protected member within the scope, not the instantiation. Instantiation was written because the above
example was having a reference being instantiated, just for clarity purpose.
On a broader scope it is related to access private/protected member
within scope of the class.

Ben
 
Ronald Schild
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Ben!
 
Ben Zaidi
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ronald,

We are accessing the private variable within scope of class
'A'. It means class B object is instantiated from scope of
class A, where 'i' is visible to A, because it lies in its
scope. It can access it, no matter what methodolgy you are
opting for accessing the private member. Here only methodology
of accessing i was different.

If you reverse the situation, we are trying to access 'i'
from scope of class B for which 'i' doesn't even exist.
Try having setters and mutators for 'i' in class A and
then try accessing the value in class B, it will follow
the standards principles of OOP i.e. Encapsulation. :^)

Hope this helps. Keep sharing.
Ben
 
Marvin Lew
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Ben,

Thank you so much for your posts. They really clear things up for me.

Just curious. You mentioned that the problem is related to accessing within some certain scope, rather than instantiation. So what methods do you think are there to access the private member i in the scope of class A, in addition to the one I have, and to produce the same effect (i.e., being able to access a private member of another non-parent class)? Or am I misled somehow?

BTW, it seems to me that b is a local variable in class A, rather than a member.
 
Ben Zaidi
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Marvin,

The terms had been used to refer to different scenario's. There can
be certain ways to access a private variable. Like you can access the
private members of the Non-direct parent class through setters and mutators.
Yes, that is true B is a local variable, rather then a member. Just i
am talking about the picture in bigger prospect, that whatever the way
we try to access a private/protected variable i.e. either through the child class reference or some other way, but it should be within the scope of that
class. Hope this helps.

Ben
 
Marvin Lew
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Ben,

Thank you.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic