Difference Between Calling SuperClass Constructor or Inherited Set Method

C

crouse

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.

Thanks a Million,

EVAC
 
E

Eric Sosman

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).
 
G

Greg R. Broderick

(e-mail address removed) wrote in @h48g2000cwc.googlegroups.com:
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;
}
}

Additionally, it is bad form to call an overridable method in a constructor
(base class or otherwise), because:

1. it is a potential security hole

2. it runs the risk (if you actually do override the method in the derived
class) of calling a method on an incompletely-constructed object, which is a
Very Bad Thing!

See "Effective Java" by Joshua Bloch for more information.

You can fix this by either making setBaseVar() final or by making it private.
If you make the method private, then you cannot call it from the derived
class, so it seems as if it would be better to just call super() in the
derived class' constructor.


Cheers
GRB

--
---------------------------------------------------------------------
Greg R. Broderick (e-mail address removed)

A. Top posters.
Q. What is the most annoying thing on Usenet?
---------------------------------------------------------------------
 
E

Erick Crouse

Greg said:
(e-mail address removed) wrote in @h48g2000cwc.googlegroups.com:

Thanks Greg for the valuable insight. I have seen it used like this
before, that is with set methods inside the constructor, but now I know
how to use them correctly by using final or private if I absolutely
need to. So that does help me differentiate between why one would use
super as opposed to set methods in a constructor.

THANKS A MILLION!

EVAC
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top