Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2006

Tip: Looking for answers? Try searching our database.

Difference Between Calling SuperClass Constructor or Inherited Set Method

Thread view: 
crouse@physics.wm.edu - 14 Aug 2006 20:16 GMT
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
Eric Sosman - 14 Aug 2006 21:32 GMT
crouse@physics.wm.edu wrote On 08/14/06 15:16,:
> Hello Everyone,
>
[quoted text clipped - 39 lines]
> 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).

Signature

Eric.Sosman@sun.com

Greg R. Broderick - 15 Aug 2006 03:09 GMT
crouse@physics.wm.edu wrote in news:1155583010.852503.219290
@h48g2000cwc.googlegroups.com:

> Hello Everyone,
>
[quoted text clipped - 29 lines]
>     }
>}

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

Signature

---------------------------------------------------------------------
Greg R. Broderick            gregb.usenet200607@blackholio.dyndns.org

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

Erick Crouse - 18 Aug 2006 12:02 GMT
> crouse@physics.wm.edu wrote in news:1155583010.852503.219290
> @h48g2000cwc.googlegroups.com:
[quoted text clipped - 32 lines]
> >     }
> >}

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

> Additionally, it is bad form to call an overridable method in a constructor
> (base class or otherwise), because:
[quoted text clipped - 22 lines]
> Q. What is the most annoying thing on Usenet?
> ---------------------------------------------------------------------


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.