Professional Documents
Culture Documents
Reference:
You may find it useful to look at the Java tutorial, taken from the Sun Java website, on
the intranet – browse to Computers, Course Materials and look under the heading for
this course.
1 Overview
This handout covers in greater depth the OO concept of inheritance and how it is used
in Java. Abstract classes and interfaces, and their uses, are discussed.
A subclass automatically inherits data and methods from its super class. These are as
follows:
A class that is declared as final cannot be extended. A final class should be used where
the class defines functionality that should not be changed in the program or any
programs using it. For example:
Page 1 of 12
8966474.doc FBE – Computer Science Dept
For example:
class SuperClass {
int x;
}
The float variable x hides the int variable x. If x is accessed in the class SubClass, it is
accessing the float variable. However, the int variable x can be accessed using the
super keyword. Super refers to the super class. Another keyword, this can be used to
access the x variable in the subclass – this is the same as just accessing x, but it makes
it clear which x is being accessed.
In practice, it is rare to hide a super class variable – it is more likely that the variable
in the subclass represents a different data member of the class, so it should have a
different name.
2.3 Overriding Super Class Methods
If the subclass declares a method with the same name, return type and parameter list
(this is also known as the signature of the method) as a method in the super class, the
subclass does not inherit the method from the super class. We say that the subclass
overrides the method.
When the method is invoked for objects of that class, the interpreter calls the new
definition of the method, not the super class's definition of the method.
Note that if the subclass declares a method with the same name but with a different
parameter list, then it is not overriding the method in the super class. It is overloading
the method. An overloaded method can also appear in the same class i.e. two methods
with the same name but with different parameter lists can appear in the same class. At
runtime, the interpreter determines which method to call based on the parameter list.
The keyword super can be used to invoke the method of the super class. This is often
used because the overriding method in the subclass is simple adding more
functionality to the method in the super class. Consider the following classes, showing
a simple initial implementation of the Person and Employee classes (as depicted in
Figure 5, on page 7 of Handout 1). The getDetails() method of the Person super class
is overridden in the Employee class. It makes a call to the super class method to avoid
duplicating the code to get the name, address and date of birth instance variable
values.
Page 2 of 12
8966474.doc FBE – Computer Science Dept
import java.util.Date;
class Person {
}
}
The subclass method that overrides a method in the super class must have the same
return type – if it does not, the compiler will report an error. This makes sense,
because if the overriding method needs to return a different data type, then it is likely
that the method is actually performing a different function, so it should have a
different name.
Page 3 of 12
8966474.doc FBE – Computer Science Dept
same way that instance variables can be hidden – by declaring a static method
in the subclass, with the same name and signature as the super class method.
3 Access Modifiers
We have seen various access modifiers being used in the classes we have worked with
so far. It is important to be aware of the meanings of these modifiers. As mentioned
above, they impact what a subclass can inherit from super classes.
Public
A public variable or method is accessible to all other classes and subclasses.
Package
Package access is also known as ‘friendly’ access. A class can be assigned to be part
of a package. Usually, a group of related classes are assigned to the same package. In
Java itself, for example, all IO classes are in the java.io package.
If no access modifier is specified for a variable or method, it is accessible only to
other classes and subclasses that are in the same package.
Protected
A protected variable or method is accessible to classes and subclasses in the same
package and also to subclasses in other packages. The visibility level of a protected
member is between the levels of public and package access.
Private
A private variable or method is accessible only within the class in which it is declared.
It is not accessible to subclasses. In other words, a private variable or method is not
inherited by subclasses.
A class itself can be declared as public, but cannot be declared as private or protected.
If a class has no access modifier specified, it is accessible only in its own package.
A class that is declared public is accessible anywhere its package is accessible.
The visibility of class members for the different access modifiers are summarised in
the table below.
Access modifier
Accessible to Public Protected Package (friendly) Private
Same class Yes Yes Yes Yes
Subclass in same Yes Yes Yes No
package
Other classes in Yes Yes Yes No
same package
Subclass in other Yes Yes No No
package
Non-subclass in Yes No No No
other package
The programmer should use the access modifiers to protect the data inside a class,
thus applying the OO concept of data encapsulation. Guidelines for deciding what
access modifiers to use are as follows:
Page 4 of 12
8966474.doc FBE – Computer Science Dept
• Use public only for methods and constants (not variables) that form part of the
public API1 (Application Programming Interface) of the class. If there are
member variables that are important or frequently used, they can be public -
but it is more common and good practice to make all fields non-public and
encapsulate them with public accessor methods (e.g. public String getName(),
public String getAddress()). Public members should be documented so that the
API informs other programmers about them. Remember that if changes are
made to anything that is part of the API of a program, they can potentially
break code that relies on the API.
• Use protected for variables and methods that are not required by most
programmers using the class, but that may be of interest to anyone creating
subclass as part of a different package. Protected members are technically part
of the API of a class – so they should be documented and changes may break
other code relying on the API.
• Use the default package visibility for variables and methods that are internal
implementation details, but may be used by cooperating classes in the same
package. To do this, you need to use the package directive at the top of a class.
• Use private for variables and methods that are used only inside the class and
should be hidden everywhere else.
It is important to be aware of how the Java compiler and interpreter deal with an
inheritance hierarchy. We have already discussed how methods can be overridden and
how member variables can be hidden.
Inheritance also has implications for the constructors of an object.
If the subclass constructor does not explicitly call the constructor of the super class,
the Java compiler automatically inserts a call to the default constructor of the super
class (the default constructor is the one that takes no parameters).
Alternatively, the programmer can do this explicitly in the code by using the super()
keyword i.e.
1
API: Application Programming Interface. This is a general programming term that refers to those
parts of a program that are exposed for use by other programs and programmers. An API often also
includes the documentation about the program. For Java, this means the JavaDoc documentation about
the classes in the program.
Page 5 of 12
8966474.doc FBE – Computer Science Dept
If the super class has a constructor that takes parameters, it must be explicitly called
by the programmer e.g.
If the call to the super class constructor has the wrong number of type of parameters,
the compiler will report an error.
In the same way that an overriding method in a subclass often just adds functionality
to the method in the super class, the constructor in a subclass may just add more steps
to the super class constructor.
Consider the Person and Employee classes again. The Person class might have a
constructor like this:
/**
Constructor
*/
public Person (String firstName, String fathersName, String address,
Date dateOfBirth)
{
name = firstName + " " + fathersName;
this.address = address;
this.dateOfBirth = dateOfBirth;
Note the use of the this keyword – this accesses a variable whose scope is the object
or instance. If the line 'this.address = address' were to read 'address = address' , it
would only be setting the parameter variable address to be its own value, it would not
be setting the address instance variable. The this keyword cannot be used in class
methods (declared using the static keyword) – because class methods are not
associated with instances, only with the class.
The constructor for the Employee class would need to pass the name, address and date
of birth values to the super class, and also set its own instance variables. So it might
be like this:
/**
Constructor
*/
Page 6 of 12
8966474.doc FBE – Computer Science Dept
It is better to explicitly call the super class constructor, even it has no parameters (i.e.
the call is just super()) as this makes it clear to another programmer that there is a
super class involved.
/**
Constructor to use when rank is not available (default to null)
*/
public Employee (String firstName, String fathersName, String
address, Date dateOfBirth,
long salary, String dept)
{
//call the main constructor, giving NULL as the rank
this (firstName, fathersName, address, dateOfBirth, salary,
dept, null);
}
5 Abstract Classes
In Handout 1, the idea of an abstract class was mentioned. An abstract class is a class
from which objects cannot be instantiated.
To make a Java class abstract, the class must be declared using the abstract keyword.
For example, if we want to ensure that a Person object is never instantiated, because a
person must be an Employee (or some other, as yet undefined, subclass of Person), we
can declare it like this:
The keyword abstract appears before the class keyword, but after the access modifier
for the class (if any).
Methods can also be declared as abstract. An abstract method does not have a body
i.e. it has no statements. It only declares the method name, access modifier, return
type and parameters. The method must have a semi-colon to indicate the empty body.
All subclasses must define an implementation of the abstract method.
Consider a program that defines classes for different shapes. All the shapes might
have a common super class named Shape. It does not make sense to instantiate an
Page 7 of 12
8966474.doc FBE – Computer Science Dept
object of type Shape, as it must be a circle or a triangle or a square etc. So the Shape
class would be abstract. If we want to ensure that all subclasses implement methods to
calculate the area and the circumference of the shape, we can add abstract methods to
the Shape class.
Any subclass of Shape must now provide its own implementation of the area and
circumference methods.
/**
* Constructor for objects of class Circle
*/
public Circle(double a_Radius)
{
radius = a_Radius;
}
• If a class has one or more abstract methods, the class itself must be declared as
abstract.
• Static, private and final methods cannot be abstract – because these types of
method cannot be overridden by subclasses.
• A final class cannot have any abstract methods.
• If a subclass of an abstract class does not implement all the abstract methods it
inherits, then that class is itself abstract.
• Objects of a subclass can only be instantiated if the subclass overrides all of
the abstract methods of the super class and provides an implementation (a
method body) for all of them. This is a concrete class.
• An abstract class can have non-abstract methods. These methods do not have
to be overridden by subclasses, but they can be if necessary.
Page 8 of 12
8966474.doc FBE – Computer Science Dept
This holds for any variable – a variable can hold objects of the declared type of the
variable (e.g. Shape ) or of any subtype of the declared type (e.g. Circle, Square).
Here, the class is the type of the variable and subtype objects may be used wherever
objects of a super type are expected. This is known as substitution (because the
subtype can be substituted for the super type) and is similar to a widening conversion
between primitive data types e.g. a short literal value can be assigned to an int
variable.
The code iterates through the shapes array and prints out the area of each element, by
calling the area() method of each Shape object. The area() method for the Shape class
does not have an implementation, but the interpreter determines which area method to
invoke by checking the type of the object at the current element in the array. This is
the OO concept of dynamic (late) binding.
To see why the area() method must be declared in the super class as well as in the
subclasses, take the Shape class and comment out the line that declares the area()
method, compile the class and then try to compile TestShapes. The compiler will
report an error like 'cannot resolve symbol' for 'method area()'.
Casting Objects
In the above example, the placing of a Circle object in an array of shapes was
effectively a widening conversion.
Page 9 of 12
8966474.doc FBE – Computer Science Dept
If we want to take an object from the array and work with it, we may want to assign it
to a variable of type Circle. For example, add the following code into the TestShapes
class, in the main method and try to compile:
Circle c;
c = shapes[0];
The compiler will report an 'incompatible types' error, stating 'found: Shape; required:
Circle'. This is because an object of a super class of Circle, the type for c, cannot be
assigned to c. A cast is necessary i.e.
Circle c;
c = (Circle) shapes[0];
This is similar to a narrowing conversion, because the object in the array is being
converted from a Shape to a Circle i.e. from the super class to the subclass.
6 Interfaces
Java allows a class to inherit from one other class only i.e. a class can have only one
super class. However, there may be cases where it is necessary for a class to inherit
from more than one source. The Java solution to this problem is interfaces.
A class can implement one or more interfaces. An interface is a reference data type
that is very similar to a class.
For example, in the Shapes example used above, if a shape can be centred on a given
point, the shape would need to inherit from the normal (non-centred) class for that
shape. E.g., a CentredCircle class would inherit from Circle. But it would also need to
inherit methods to set the centre point and to get the coordinates of the centre.
Not all shapes are centred, so it is not ideal to put the centre point methods in the
Shape super class. So we can instead put the methods in an interface.
{
public void setCentre(double x, double y);
public double getCentreX();
public double getCentreY();
}
Note that the interface can only have abstract methods – it cannot implement the
methods.
A subclass of the Circle class can now also implement this interface. A class that
implements an interface must implement the methods in the interface.
/**
* Constructor for objects of class CentredCircle
Page 10 of 12
8966474.doc FBE – Computer Science Dept
*/
public CentredCircle(double cx, double cy, double a_Radius)
{
super (a_Radius);
this.cx = cx;
this.cy = cy;
}
Like a class, an interface is a reference data type. Therefore, when a class implements
an interface, instances of that class can be assigned to variables of the interface type.
For example, see the class TestShapesInterface. This creates an array of shape objects
and then iterates through the array to write out the area of each shape. It also tests
each shape to see if it is also a Centred shape. If it is, the centre point is also written
out.
Page 11 of 12
8966474.doc FBE – Computer Science Dept
Page 12 of 12