Explain How Super Class Variable Can Reference a Subclass Object In Java, Super Keyword In Java, Super Class In Java, Sub Class In Java
In This Topic & Blog Having Any Query Then Post your Comment and Suggestion Below

A Super Class Variable Can Reference a Subclass Object
A reference variable of a superclass can be assigned a reference to any subclass derived from
that superclass. You will find this aspect of inheritance quite useful in a variety of situations.
For example, consider the following:
class RefDemo {
public static void main(String args[]) {
BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37);
Box plainbox = new Box();
double vol;
vol = weightbox.volume();
System.out.println("Volume of weightbox is " + vol);
System.out.println("Weight of weightbox is " +
weightbox.weight);
System.out.println();
// assign BoxWeight reference to Box reference
plainbox = weightbox;
vol = plainbox.volume(); // OK, volume() defined in Box
System.out.println("Volume of plainbox is " + vol);
/* The following statement is invalid because plainbox
does not define a weight member. */
// System.out.println("Weight of plainbox is " + plainbox.weight);
}
}
Here,
weightbox
is a reference to
BoxWeight
objects, and
plainbox
is a reference to
Box
objects.
Since
BoxWeight
is a subclass of
Box
, it is permissible to assign
plainbox
a reference to the
weightbox
object.
It is important to understand that it is the type of the reference variable—not the type of
the object that it refers to—that determines what members can be accessed. That is, when a
reference to a subclass object is assigned to a superclass reference variable, you will have access
only to those parts of the object defined by the superclass. This is why
plainbox
can’t access
weight
even when it refers to a
BoxWeight
object. If you think about it, this makes sense,
because the superclass has no knowledge of what a subclass adds to it. This is why the last
line of code in the preceding fragment is commented out. It is not possible for a
Box
reference
to access the
weight
field, because
Box
does not define one.
Although the preceding may seem a bit esoteric, it has some important practical
applications—two of which are discussed later in this chapter.
Using super
In the preceding examples, classes derived from
Box
were not implemented as efficiently or
as robustly as they could have been. For example, the constructor for
BoxWeight
explicitly
initializes the
width height
,
, and
depth
fields of
Box( )
. Not only does this duplicate code
found in its superclass, which is inefficient, but it implies that a subclass must be granted access
to these members. However, there will be times when you will want to create a superclass that
keeps the details of its implementation to itself (that is, that keeps its data members private).
In this case, there would be no way for a subclass to directly access or initialize these variables
on its own. Since encapsulation is a primary attribute of OOP, it is not surprising that Java
provides a solution to this problem. Whenever a subclass needs to refer to its immediate
superclass, it can do so by use of the keyword
super
.
super
has two general forms. The first calls the superclass’ constructor. The second is
used to access a member of the superclass that has been hidden by a member of a subclass.
Each use is examined here.
Using super to Call Superclass Constructors
A subclass can call a constructor defined by its superclass by use of the following form of
super
:
super( arg - list );
Here, arg - list specifies any arguments needed by the constructor in the superclass.
super( )
must always be the first statement executed inside a subclass’ constructor.
To see how
super( )
is used, consider this improved version of the
BoxWeight( )
class:
// BoxWeight now uses super to initialize its Box attributes.
class BoxWeight extends Box {
double weight; // weight of box
// initialize width, height, and depth using super()
BoxWeight(double w, double h, double d, double m) {
super(w, h, d); // call superclass constructor
weight = m;
}
}
Here,
BoxWeight( )
calls
super( )
with the arguments
w h
,
, and
d
. This causes the
Box( )
constructor to be called, which initializes
width height
,
, and
depth
using these values.
BoxWeight
no longer initializes these values itself. It only needs to initialize the value unique
to it:
weight
. This leaves
Box
free to make these values
private
if desired.
In the preceding example,
super( )
was called with three arguments. Since constructors
can be overloaded,
super( )
can be called using any form defined by the superclass. The
constructor executed will be the one that matches the arguments. For example, here is a
complete implementation of
BoxWeight
that provides constructors for the various ways
that a box can be constructed. In each case,
super( )
is called using the appropriate arguments.
Notice that
width height
,
, and
depth
have been made private within
Box
.
// A complete implementation of BoxWeight.
class Box {
private double width;
private double height;
private double depth;
// construct clone of an object
Box(Box ob) { // pass object to constructor
width = ob.width;
height = ob.height;
depth = ob.depth;
}
// constructor used when all dimensions specified
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
// constructor used when no dimensions specified
Box() {
width = -1; // use -1 to indicate
height = -1; // an uninitialized
depth = -1; // box
}
// constructor used when cube is created
Box(double len) {
width = height = depth = len;
}
// compute and return volume
double volume() {
return width * height * depth;
}
}
// BoxWeight now fully implements all constructors.
class BoxWeight extends Box {
double weight; // weight of box
// construct clone of an object
BoxWeight(BoxWeight ob) { // pass object to constructor
super(ob);
weight = ob.weight;
}
// constructor when all parameters are specified
BoxWeight(double w, double h, double d, double m) {
164
Part I:
The Java Language
super(w, h, d); // call superclass constructor
weight = m;
}
// default constructor
BoxWeight() {
super();
weight = -1;
}
// constructor used when cube is created
BoxWeight(double len, double m) {
super(len);
weight = m;
}
}
class DemoSuper {
public static void main(String args[]) {
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
BoxWeight mybox3 = new BoxWeight(); // default
BoxWeight mycube = new BoxWeight(3, 2);
BoxWeight myclone = new BoxWeight(mybox1);
double vol;
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
System.out.println("Weight of mybox1 is " + mybox1.weight);
System.out.println();
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
System.out.println("Weight of mybox2 is " + mybox2.weight);
System.out.println();
vol = mybox3.volume();
System.out.println("Volume of mybox3 is " + vol);
System.out.println("Weight of mybox3 is " + mybox3.weight);
System.out.println();
vol = myclone.volume();
System.out.println("Volume of myclone is " + vol);
System.out.println("Weight of myclone is " + myclone.weight);
System.out.println();
vol = mycube.volume();
System.out.println("Volume of mycube is " + vol);
System.out.println("Weight of mycube is " + mycube.weight);
System.out.println();
}
}
This program generates the following output:
Volume of mybox1 is 3000.0
Weight of mybox1 is 34.3
Volume of mybox2 is 24.0
Weight of mybox2 is 0.076
Volume of mybox3 is -1.0
Weight of mybox3 is -1.0
Volume of myclone is 3000.0
Weight of myclone is 34.3
Volume of mycube is 27.0
Weight of mycube is 2.0
Pay special attention to this constructor in
BoxWeight( )
:
// construct clone of an object
BoxWeight(BoxWeight ob) { // pass object to constructor
super(ob);
weight = ob.weight;
}
Notice that
super( )
is passed an object of type
BoxWeight
—not of type
Box
. This still
invokes the constructor
Box(Box ob)
. As mentioned earlier, a superclass variable can be
used to reference any object derived from that class. Thus, we are able to pass a
BoxWeight
object to the
Box
constructor. Of course,
Box
only has knowledge of its own members.
Let’s review the key concepts behind
super( )
. When a subclass calls
super( )
, it is calling
the constructor of its immediate superclass. Thus,
super( )
always refers to the superclass
immediately above the calling class. This is true even in a multileveled hierarchy. Also,
super( )
must always be the first statement executed inside a subclass constructor.
A Second Use for super
The second form of
super
acts somewhat like
this
, except that it always refers to the superclass
of the subclass in which it is used. This usage has the following general form:
super. member
Here, member can be either a method or an instance variable.
This second form of
super
is most applicable to situations in which member names of
a subclass hide members by the same name in the superclass. Consider this simple class
hierarchy:
// Using super to overcome name hiding.
class A {
int i;
}
// Create a subclass by extending class A.
class B extends A {
int i; // this i hides the i in A
B(int a, int b) {
super.i = a; // i in A
i = b; // i in B
}
void show() {
System.out.println("i in superclass: " + super.i);
System.out.println("i in subclass: " + i);
}
}
class UseSuper {
public static void main(String args[]) {
B subOb = new B(1, 2);
subOb.show();
}
}
This program displays the following:
i in superclass: 1
i in subclass: 2
Although the instance variable
i
in
B
hides the
i
in
A super
,
allows access to the
i
defined
in the superclass. As you will see,
super
can also be used to call methods that are hidden by a
subclass.
Labels: Java - J2SE