Re: Question on member accessibility
ankur wrote:
public class SuperA {
protected void superMethA()
{
}
}
public class SubB extends SuperA {
SubB varB = new SubB();
SuperA varA = new SuperA();
void subMethB()
{
varB.superMethA();
superMethA();
varA.superMethA(); // (4)Why this does not work
}
}
Why (4) does not work ? I could not understand ( appreciate) the
reason why this access is denied !
It has already been explained that it is not allowed per language
rules.
It is not allowed in C# or C++ either.
Why ?
Peter guessed:
# As for why the rule exists, that gets a bit more speculative on my
part, since
# I'm not the one who designed Java or similar languages. However, I
think it's a
# reasonable rule, since the "protected" access is there to allow
sub-classes
# better control over _themselves_, not other classes. The class "SubB"
really
# should only have permission to touch "protected" members for instances of
# itself. The alternative does not provide enough protection for
sub-classes that
# are otherwise unrelated to "SubB".
#
# For example, imagine how disruptive you could be if you could write a
JComponent
# sub-class that could retrieve a Graphics instance used to paint _some
other_
# JComponent sub-class by calling the protected method
getComponentGraphics().
# That method is intended for an instance to use internally to get its own
# Graphics instance, not some other instance's.
#
# Or consider (again in JComponent) the protected method
requestFocusInWindow().
# Again, intended for use for a JComponent instance on _its own_ behalf.
Other
# code could be disruptive by calling some other instance's
requestFocusInWindow()
# method (especially if that other instance was a sub-class that wasn't even
# supposed to have the focus).
#
# In fact, people could wind up writing sub-classes of certain classes
for the
# sole purpose of messing around with _other_ sub-classes of those
classes. That
# breaks encapsulation in some very important ways, and so it's not allowed.
Joshua guessed:
# I don't know the entire rationale behind this, but this is my guess.
# The purpose of protected, in the inheritance sense, is to say that
# "this property is one I wish to expose to people who need to implement
# me but not those who wish to merely use me." So, let us form the
# class:
#
# class Foo {
# protected int importantFieldForInternalUse;
# }
#
# Since it's internal, we don't want people mucking about with it, but
# our subclass needs to use it. But Joe Hacker comes along and says "if
# only I change that important field..." Since Foo is created by other
# stuff and passed around by methods, he gets a hold of it to his class:
#
# class Evil extends Foo {
# public static void manipulateFoo(Foo object) {
# // Bwa-ha-ha! I broke it all!
# object.importantFieldForInternalUse = 0;
# }
#}
Those are all good reasons.
But I think that for methods there are at least one more reason.
It is not only methods that exist in the super class that would
get exposed but also overriding virtual methods in sub classes.
public class Sup {
protected void test() {
}
}
public class SubA extends Sup {
protected void test() {
}
}
public class SubB extends Sup {
public void foobar(Sup o) {
o.test();
}
}
SubB o = new SubB();
o.foobar(new SubA());
It seems rather obvious that SubB should not have access to run
code in a protected method in SubA.
Arne