Re: Accessing private member via subclass
Michal Kleczek wrote:
markspace wrote:
Mike Schilling wrote:
public abstract class Super
{
private int i;
void method(Sub s) // <-- Oops
Any thoughts about this?
I was pretty mystified by your example until I did a second glance at
the line labeled "Oops". Well, obviously if the type of "s" is NOT the
type that holds the private field "i", you can't access "i" through that
type. I think that should be completely intuitive.
Someone else mentioned that Sub could have a public field "i" added at
some point, in which case you'd (likely) have an erroneously behaving
Super.
But it does not have anything to do with 'i' being accessible or not. The
issue would remain if you change 'i' to public in the original example (and
it will compile fine).
My thought on realizing this was that C# is defective in this
regard and Java is correct.
IMHO it is better done in C# - more regular.
I like a lot of things about C# - I prefer that language to Java - but I
sure don't like *this*. I don't find it "regular" at all.
The C# documentation makes it clear that private member fields are not
accessible to derived classes. This - to me - does not conflict with the
statement that private fields _are_ accessible in the owning class,
because in the example we are _not_ referring to an unadorned "i", we're
referring to "s.i", where "s" is an instance of a derived class. That
"s.i" notation, again to me, is the nub of the whole matter - we are
accessing through the derived class, and it's not supposed to have
access to that field. Regardless of the fact that that access is
happening lexically inside the body of the base class.
In Java things get strange sometimes due to such irregularities. Look at the
following:
public class Super {
private int i;
<T extends Super> void m(T s) {
s.i = 5;
}
}
This compiles fine in Java - should it?
I believe it should. When using "extends", that reference "s" must
behave as an instance of Super; we can't use or guess at any extended
behaviour of a specific T. For example, if you had a List<? extends
Number>, reading from (accessing) that List gives you a Number.
In this case, being in the body of S, getting or setting a private
member field of S is OK.
AHS