Hello Everyone,
This is the situation. I have the usual base class w/ private instance
variable along with public methods manipulating them. I have a derived
class which inherits from the base class.
public class Base {
private int base;
Base() {
setBaseVar( 100 );
}
Base( int value ) {
setBaseVar( value );
}
public setBaseVar( int val ) {
base = val;
}
}
public classe Derived{
private int derived;
Derived( int derived ) {
super();
setDerivedVar( derived );
}
*Derived( int derived ) { // Alternative
setBaseVar( 100 )
setDerivedVar( derived );
}
setDerivedVar( int val ) {
derived = val;
}
}
Is there any difference between Derived and *Derived constructors in
assigning a value to base using a call to super or inherited access
method? When calling an inherited member function ( a setter method,
for example ) from a derived class object, and setting the private
instance variable of the base class, what has happened? Because there
is no base class object (I'm assuming this) we must be setting an
instance variable of the Derived class, but it was inherited and
shouldn't even be visible technically although we have still set it.
I'm confused.
So am I, because the code you have shown makes no
sense. It will not even compile, so there's not much
point in trying to discuss subtle issues about its
behavior. For starters,
- There is no `classe' keyword in Java. I imagine
you meant `class'.
- As written, Derived inherits directly from Object
and is not a subclass of Base. I imagine you meant
`public class Derived extends Base'.
- The `*' character cannot be used as part of an
identifier. You might replace `*Derived' with
`Derived' ...
- ... but then you would have two constructors with
identical signatures, which is not allowed. I'll
assume your intent is to have either the first or
the second Derived constructor, but not both (and
not neither).
With those corrections assumed (and if I've mis-guessed,
it's your fault for making me guess in the first place), I'll
try to answer what I think your questions are.
Let's start by supposing the Derived class is written with
(only) the first form of the constructor. That constructor
begins by calling super() to construct a Base object (the
compiler would have inserted this call automatically if you had
omitted it). The Base constructor with no arguments begins by
calling super() to construct an Object object (there's the
automatic insertion at work), then finishes constructing the
Base object by calling setBaseVar(100). That completes the
construction of a Base instance, so now it's back to the Derived
constructor. This constructor finishes constructing its Derived
instance by calling setDerivedVar(derived), which is just a
fancy no-op (it sets the private field to the value it already
has, which is zero).
Now let's throw away the first Derived constructor and
substitute the second in its place. This constructor begins
by calling super() to construct a Base instance (there's the
automatic insertion again), and as before the no-arguments Base
constructor goes about its business of building a Base object.
When it returns, the Derived constructor then calls a method
of that Base object; the Base object has been constructed (by
Base's own constructor), so calling a method on the Base object
is nothing out of the ordinary. Then the Derived constructor
calls a method of the Derived object being constructed; as
before, this method call is just a fancy no-op.
I hope that addresses your confusion about construction;
it might be a good idea to re-read parts of your Java textbook
at this point.
Now to the visibility question: You seem confused about the
fact that the public method setBaseVar() can access the private
instance variable base, even when the call to setBaseVar() is
made from another class' code. That is perfectly normal: the
setBaseVar() method is part of the implementation of the Base
class, so it has access to all the internals of Base, even those
that are private. Meanwhile, setBaseVar() is a public method,
so any class can call it.
Since a Derived instance "is a" Base instance, every Derived
object there has a base field -- but that field is accessible
only by Base's own code, and not by the code in Derived. The
Derived object "owns" some state that it cannot see or touch.
As it happens, Base provides a method that allows Derived to
set the field's value. Derived can use that method but cannot
really control what it does; it just has to have faith that the
method will have the effect Base's documentation promises. The
details of how that effect is achieved are hidden; only Base
knows how its own magic works.
This arrangement has familiar parallels in the real world.
A Starbuck's shop has "public methods" that anyone can call
(the shop staff), and those "methods" carry out their tasks by
accessing "private state" (the espresso machine) that is off-
limits to outsiders. You are an outsider and lack the privilege
to operate the espresso machine, but that doesn't prevent you
from ordering an espresso and receiving it (and paying too much).