Overloading, Overriding, Runtime Type and Object Orientated
With this section it should help you
to be able to do the following.
1. State benefits of encapsulation in OOD and write code
that implements tightly encapsulated classes and the relationships “is a”
and “has a”.
2. Write code to invoke overridden or overloaded methods
and parental or overloaded constructors; and describe the effect of invoking
these methods.
3. Write code to construct instances of any concrete
class including normal top level classes and nested classes.
Overloading,
Overriding, Runtime Type and Object Orientated
The benefits of OOD come from two particular
features of the OO concept. The first is the notion of an abstract data type
and the second is the extensibility provided by inheritance.
Abstract
Data Types
An abstract data type is really just a fancy
name for a well-encapsulated aggregate of data and behaviour.
The Java™ language allows a class to
declare a method without any implementation. (The implementation for the method
is supplied in a subclass of that class.) The method with no implementation is
known as an abstract method and any class that declares one or more abstract
methods is known as an abstract class.
You cannot create an instance of an abstract
class. Any attempt to do so will give a complier error. Its purpose is to be a superclass to related subclasses.
If an abstract method is defined within a
class, the class must be defined as abstract. However, an abstract class does
not necessarily have to contain an abstract method (but usually does).
abstract class ClassName
{
// definition of variables
// definition of methods
} // end of abstract
class
In addition an abstract class can include
any or all of the following:
·
data
·
constructors
·
fully
implemented methods (known as “concrete methods”)
If we look at the following code, the first
is an example of an abstract class:
public abstract class AbstractTestClass
{
//test methods
public abstract int plus(int i);
public abstract int minus(int i);
public void outputTest()
{
System.out.println("This has been printed - coded originally in the
abstract class");
}
} //end of AbstractTestClass
And run the following test class which
extends the AbstractTestClass
public class test extends AbstractTestClass
{
public static void
main(String[] args)
{
int
i = 5;
test t = new
test();
t.plus(i);
t.minus(i);
t.outputTest();
}
//The plus method is an abstract class so
needs defining
public int plus(int i)
{
System.out.println(i + " + " + i + " = " + (i+i));
return(i+i);
}
//The minus method is an abstract class so
needs defining
public int minus(int i)
{
System.out.println(i + " - " + i + " = " + (i-i));
return(i-i);
}
}//end of test class
We get the following result
There are a number of restrictions when
using the abstract keyword
1. Constructors cannot be declared abstract
If a constructor
was abstract, it would have to be overridden in the subclass. However this can
never happen because constructors are not inherited and therefore cannot be
overridden.
2. Private methods cannot be declared abstract.
A private method
in a class is not visible in a subclass. Therefore if the private method was
allowed to be abstract it could not be overridden.
This is a form of encapsulation.
Inheritance
This is also seen in the above example where
the test object not only defined the two abstract classes, it inherited the OutputTest method. This is a very simple example but if a
class is well encapsulated, it will be easier to reuse successfully and make
overall coding of large programs much simpler, inheritance is a very powerful
feature and can determine how you design and write your classes.
Inheritance enables new classes to be created
based on other classes.
A class can have any number of subclasses
however a class (subclass) can only have one superclass.
If no superclasses are declared then the Object class
is extended by default.
For example:
The Circle, Square and Rectangle classes all
have one superclass, the Shape class.
Example code
//File
called Shape.java public class Shape { private
double area; private
double perimeter; public
void setArea(double area) { this.area =
area; } public
void setPerimeter(double perimeter) { this.perimeter
= perimeter; } public
double getArea() { return area; } public
double getPerimeter() { return perimeter; } } //end of shape class |
|
//File
called Circle.java public
class Circle extends Shape { private double radius; public void calcArea() { setArea(3.14 * radius * radius); } public void calcPerimeter() { setPerimeter(2 * 3.14 * radius); } }
//end of Circle class |
The circle is a shape, as are the Square and Rectangle. The Circle has a radius property.
Overloading
and Overriding
Reusing the same method name with different
arguments and perhaps different return types is known as overloading.
Using the same method name with identical
arguments and return type is known as overriding.
Rules
for Overloading and Overriding
·
A method can
have the same name as another method in the same class, providing it forms
either a valid overload or override.
·
A valid overload
differs in the number of types of its arguments. Differences in arguments names
are not significant. A different return type is permitted, but it is not
sufficient by itself to distinguish an overloading method.
·
Methods that
overload a name are different methods and can coexist in a single class.
·
Both overloaded
and overloading methods are accessed simply by providing the correct argument
types for the method call.
·
A valid override
has identical argument types and order, identical return type, and is not less
accessible than the original method. The overriding method must not throw any
checked exceptions that were illegal for the original method.
·