|
JavaFAQ Home » Java Lessons by Jon Huhtala

Inheritance and overriding inherited methods
Overview
Object-oriented design implements two simple
relationships:
"has
a" and
"is a"
You have already seen many examples of the "has a" relationship. It is implemented by the
instance variables of a class. For example, consider the following class for
maintaining and processing certain Vehicle data:
class Vehicle { private String description; private int
capacity; private double maxSpeed; public Vehicle(String
iDescription, int iCapacity, double iMaxSpeed) {
setDescription(iDescription);
setCapacity(iCapacity);
setMaxSpeed(iMaxSpeed); } public void
setDescription(String nDescription) { description =
nDescription; } public boolean setCapacity(int nCapacity)
{ if (nCapacity >= 0)
{ capacity =
nCapacity; return
true; }
else return false;
} public boolean setMaxSpeed(double nMaxSpeed)
{ if (nMaxSpeed > 0)
{ maxSpeed =
nMaxSpeed; return
true; }
else return false; }
public String getDescription() { return
description; } public int getCapacity()
{ return capacity; } public double
getMaxSpeed() { return maxSpeed;
} }
According to this class definition, a Vehicle "has a" description, "has
a" passenger capacity, and "has a" maximum speed. Notice that the relationship
can be implemented by either a primitive variable or a reference to an object of
another class (a String
object is used to maintain the Vehicle description).
While the "has a" relationship is implemented
through the instance variables of a class, the "is
a" relationship is implemented by extending an existing class.
Extending a class
-
Defines a new class that "is a" more specific
version of the class being extended. For example, a Bicycle class can be defined that extends the
Vehicle class. After all,
a Bicycle "is a" Vehicle. As an extension of
Vehicle, the Bicycle class would inherit all
the features of the Vehicle class and could add additional features.
The class hierarchy would actually be
indicating that a Bicycle "is a" Vehicle and a Vehicle "is an" Object. As a custom class, the Vehicle class is automatically
an extension of Java's Object class and inherits all its features. The Object class is the "root" of
the class hierarchy.
-
Is sometimes called "subclassing". The class
being extended is referred to as the "superclass" (or parent) and the new
class is referred to as its "subclass" (or child). A class can be both a
subclass and a superclass. In the above class hierarchy, the Vehicle class is a subclass of
Object and a superclass
of Bicycle.
In Java, a class can never have more than one
superclass. This is called "single inheritance" and is a fundamental
difference between Java and C++ (which permits "multiple inheritance).
While a Java class can have only one
superclass, it can be extended to have any number of subclasses. For example,
the Vehicle class can be
extended to create classes such as AirPlane, Automobile, HotAirBalloon, OxCart, etc.
A class inherits all features of the classes
above it in the class hierarchy. Such classes are referred to as its
"ancestors".
class Bicycle extends Vehicle
-
Has an impact on how an object of the class is
constructed. During instantiation, the constructor methods of all ancestor
classes must be executed. For example, a Bicycle object depends upon its inherited Vehicle class and Object class features being
properly initialized.
To accomplish this, the first thing each
subclass constructor MUST do is call its superclass constructor as shown by
this diagram:
|
Bicycle |
|
Vehicle |
|
Object |
|
constructor |
|
constructor |
|
constructor |
|
|
|
|
|
|
1) Call superclass
constructor |
--> |
1) Call superclass
constructor |
--> |
Complete construction |
|
2) Complete construction |
<-- |
2) Complete construction |
<-- |
The call to the default (no argument)
superclass constructor is automatically generated by the Java compiler. This
makes it easy to define a first-generation custom class, such as Vehicle. It needn't be
concerned with calling the constructor of the Object class because it happens automatically.
When extending a class, it is necessary to call
a superclass constructor that accepts parameters. To do so, the call must be
explicitly coded as the first statement within the constructor. The syntax of
the call is as follows:
super(arguments);
The keyword super always references the immediate superclass
of the current object. When used as a method name, it indicates a call to the
superclass constructor. Based upon the arguments being passed, the correct
overloaded superclass constructor will be called.
public class App { public static void main(String[] args)
{ Bicycle bike = new Bicycle("Mary's old bike", 1,
15.5, 14, true); Utility.skip();
System.out.println(" Description:
" + bike.getDescription());
System.out.println(" Wheel diameter: " +
bike.getWheelDiameter());
System.out.println("
Top speed: " + bike.getMaxSpeed());
bike.setDescription("Mary's modified bike");
bike.setWheelDiameter(1 ;
bike.setMaxSpeed(22.5);
Utility.skip();
System.out.println(" Description:
" + bike.getDescription());
System.out.println(" Wheel diameter: " +
bike.getWheelDiameter());
System.out.println("
Top speed: " + bike.getMaxSpeed());
Utility.skip(); System.out.println(" Object
information: " + bike.toString()); } }
class Vehicle { private
String description; private int capacity; private double
maxSpeed; public Vehicle(String iDescription, int iCapacity,
double iMaxSpeed) {
setDescription(iDescription);
setCapacity(iCapacity);
setMaxSpeed(iMaxSpeed); } public void
setDescription(String nDescription) { description =
nDescription; } public boolean setCapacity(int
nCapacity) { if (nCapacity >= 0)
{ capacity =
nCapacity; return
true; }
else return false;
} public boolean setMaxSpeed(double nMaxSpeed)
{ if (nMaxSpeed > 0)
{ maxSpeed =
nMaxSpeed; return
true; }
else return false; }
public String getDescription() { return
description; } public int getCapacity()
{ return capacity; } public double
getMaxSpeed() { return maxSpeed;
} }
class
Bicycle extends Vehicle { private int wheelDiameter; private boolean
hasBell; public Bicycle(String iDescription, int iCapacity, double
iMaxSpeed,
int iWheelDiameter, boolean iHasBell) { super(iDescription, iCapacity,
iMaxSpeed);
setWheelDiameter(iWheelDiameter);
setHasBell(iHasBell); } public boolean
setWheelDiameter(int nWheelDiameter) { if
(nWheelDiameter >= 12 && nWheelDiameter <= 26)
{ wheelDiameter =
nWheelDiameter; return
true; }
else return false; }
public void setHasBell(boolean nHasBell) { hasBell =
nHasBell; } public int getWheelDiameter()
{ return wheelDiameter; } public
boolean hasBell() { return hasBell;
} }
Notes:
-
When the application instantiates the Bicycle object, the Bicycle constructor passes
the description, capacity, and maximum speed through to the superclass
(Vehicle)
constructor.
-
As the application acts upon the Bicycle object (bike), it calls the
object's instance methods without regard to their class. For example, the
getDescription()
method is in the Vehicle class, the setWheelDiameter() method is in the Bicycle class, and the toString() method is in the Object class. The inherited
toString() method
isn't very useful, but we are about to change that.
Overriding an inherited method
-
Requires the definition of a method having the
same name, same arguments, and same return type as the inherited method. The
newly defined method hides the overridden method so that calls to the method
go to the new version and not the overridden version.
For example, all classes inherit the toString() method of the Object class. The default
behavior of the method is to return a String containing general information about the object (its
class name and the value of its object reference). To override the inherited
method to provide other information, a class could contain the method
public String toString() { custom code goes here... }
where the custom code would build and return a
String to the
caller.
-
Is NOT to be confused with overloading.
Overloading requires that the methods must differ in their signature
(arguments). Overriding requires that the method headers be identical.
-
Example: The following program is a slightly
modified version of the previous example. The only change is the overriding
toString() method in the
Bicycle class.
public class App { public static void main(String[] args)
{ Bicycle bike = new Bicycle("Mary's old bike", 1,
15.5, 14, true); Utility.skip();
System.out.println(" Description:
" + bike.getDescription());
System.out.println(" Wheel diameter: " +
bike.getWheelDiameter());
System.out.println("
Top speed: " + bike.getMaxSpeed());
bike.setDescription("Mary's modified bike");
bike.setWheelDiameter(1 ;
bike.setMaxSpeed(22.5);
Utility.skip();
System.out.println(" Description:
" + bike.getDescription());
System.out.println(" Wheel diameter: " +
bike.getWheelDiameter());
System.out.println("
Top speed: " + bike.getMaxSpeed());
Utility.skip(); System.out.println(" Object
information: " + bike.toString()); } }
class Vehicle { private
String description; private int capacity; private double
maxSpeed; public Vehicle(String iDescription, int iCapacity,
double iMaxSpeed) {
setDescription(iDescription);
setCapacity(iCapacity);
setMaxSpeed(iMaxSpeed); } public void
setDescription(String nDescription) { description =
nDescription; } public boolean setCapacity(int
nCapacity) { if (nCapacity >= 0)
{ capacity =
nCapacity; return
true; }
else return false;
} public boolean setMaxSpeed(double nMaxSpeed)
{ if (nMaxSpeed > 0)
{ maxSpeed =
nMaxSpeed; return
true; }
else return false; }
public String getDescription() { return
description; } public int getCapacity()
{ return capacity; } public double
getMaxSpeed() { return maxSpeed;
} }
class
Bicycle extends Vehicle { private int wheelDiameter;
private boolean hasBell; public Bicycle(String iDescription, int
iCapacity, double
iMaxSpeed,
int iWheelDiameter, boolean iHasBell) {
super(iDescription, iCapacity, iMaxSpeed);
setWheelDiameter(iWheelDiameter);
setHasBell(iHasBell); } public boolean
setWheelDiameter(int nWheelDiameter) { if
(nWheelDiameter >= 12 && nWheelDiameter <= 26)
{ wheelDiameter =
nWheelDiameter; return
true; }
else return false; }
public void setHasBell(boolean nHasBell) { hasBell =
nHasBell; } public int getWheelDiameter()
{ return wheelDiameter; } public
boolean hasBell() { return hasBell;
} public String toString() { String result =
"[ " + getDescription() + ", "
+
getCapacity() + ", "
+
getMaxSpeed() + ", "
+
getWheelDiameter() + ", "
+
hasBell()
+
" ]"; return result; } }
Lab exercise for Ferris
students
E-mail your answers to this
assignment no later than
the due date listed in the class schedule.
Review questions
-
You have been given the
specification for a personnel system to be implemented in Java. Part of it
states:
"An employee has an
employee number, a name, and a hire date. A sales representative is an
employee who has a commission rate and a district."
Given that the Employee class has already been defined, code
the class header of the SalesRep class
so that it can be referenced from any class.
-
You have been given the
specification for a personnel system to be implemented in Java. Part of it
states:
"An employee has an
employee number, a name, and a hire date. A sales representative is an
employee who has a commission rate and a district."
Given that the Employee class has already been defined,
which of the following fields would be appropriate for inclusion in the SalesRep class as members? (choose two)
-
Employee theEmployee;
-
double commissionRate;
-
String district;
-
String name;
-
Date hireDate;
-
Assume that class Nothing has been defined with a single
constructor that accepts a String.
Which one of the following legally define a class that extends Nothing?
-
class DoesNothing extends Nothing { private int
value; public DoesNothing(String iName, int iValue)
{ super(iName); value =
iValue; } }
-
class DoesNothing extends Nothing { private int
value; public DoesNothing(String iName, int iValue)
{ value = iValue;
super(iName); } }
-
class DoesNothing extends Nothing { private int
value; public DoesNothing(String iName, int iValue)
{ Nothing(iName); value =
iValue; } }
-
class DoesNothing extends Nothing { private int
value; public DoesNothing(String iName, int iValue)
{ super(); value =
iValue; } }
-
class DoesNothing extends Nothing { private int
value; public DoesNothing(String iName, int iValue)
{ int y = 5;
super(iName); value = iValue * y;
} }
-
Assume that a class inherits a single method named calcAmount that has the following method header:
public double
calcAmount(double discount, boolean preferred)
Which of the following is
the header of a method that can legally be coded within the class?
-
public float calcAmount(float d, boolean p)
-
public double calcAmount(double d)
-
public double calcAmount(double d, boolean p)
-
public float calcAmount(float d)
-
all of the above
Printer Friendly Page
Send to a Friend
..
Search here again if you need more info!
|