Goals: increase reusability, reliability and comprehensibility.
Relationships between classes
- One class may use another class.
- One class may contain another class. (Has-a)
- One class may inherit from another class. (is-a)
- Pay attention to the relationships between classes.
Old method: code copying.
New method: Classes with inheritance.
You can inherited methods and data.
Inheritance permits minor variation and sharing.
Polymorphism permits determination of which
function to execute at run-time, decided by object type.
Java supports single-inheritance, ie. you can inheritance
hierarchy from a tree and each object is a member of only
one tree. An argument for this is simplicity.
A limited form of multiple inheritance is achieved with interfaces,
which is the next topic.
public class NormedComplex
extends Complex // the inheritance
private double norm;
NormedComplex(double x, double y)
super(x,y); // if this is not here, super() is assumed.
// if super() not defined, compiler error.
norm = x*x-y*y;
this(0,0); // No call to super() as "this" will call super.
public void normalize()
setReal(getReal()/norm); // getReal is inherited
- Super can be used to access data member and member functions of the
superclass (the one which was extended).
- In the subclass, one can use the same variable name or method name
as in the superclass.
This shadows (hides) the inherited value. To get the inherited
value use super.x.
- One can also shadow methods, which is called overriding .
Again to get the inherited method, use super.method(...).
- You cannot go up more than one level, by using super.super....
- You can prevent shadowing/overriding by declaring the member
to be final. It is common to declare constants to be final.
- You cannot increase the accessibility in subclasses.
- Casting converts an instance of one type to another type, via
the prefix operator (type).
- Casting can be explicit or implicit.
- Examples of implicit casting:
- 3+4.2 Here 3 is cast from integer to float.
- "sam"+3 Here 3 is cast from integer to String.
- Implicit casting is also called upcasting or widening,
as the object gains additional fields, usually set to
some default value.
- Explicit casting typical narrows or removes fields, which
is called downcasting.
This can be dangerous as information maybe lost. For example:
int i = 1000;
byte b = (byte) i;
If you are sure of the range of variable's value, casting may not
hurt, as in:
int i = 4;
byte b = (int)4;
A typical use of casting occurs when retrieving elements
from some container, such as a Vector.
Vector v = new Vector();
v.addElement(Complex c = new Complex(3,4)); // c is upcast to object
Complex c1 = v.getElementAt(0); // This is an error, instead use
Complex c1 = (Complex) v.getElementAt(0); // downcasting
Notice that in Java Vectors are unsafe as Vectors (and other containers)
only hold Objects. Without undue cost, you can't enforce a Vector
of a particular type. Here Java is not as strongly typed as C++ is,
which would accomplish the task via templates.
- An abstract method consists of the signature followed by
a semicolon, e.g. double area();
- An abstract method is used to set up a promise or contract that
every concrete subclass will implement the abstract method.
- A class is abstract
if it has at least one method without an implementation or
if it is declared abstract.
- A class that contains an abstract method must be declared
- You cannot instantiated (have an instance of) an abstract class.
- Subclasses of an abstract class may be abstract.
- Subclasses of a concrete class can be abstract.
- If a subclass overrides all the abstract methods, then it
can be instantiated.
abstract class Shape // can't be instantiated
double area(); // notice prototype
class Rectangle extends Shape
double length, width;
Rectangle(double length , double width)
this.length = length;
this.width = width;
return 2*length + 2*width;
class Square extends Rectangle
class Circle extends Shape
this.radius = radius;
return Math.PI*diameter(); // you don't worry about order of declaration
Polymorphism Example 2
Suppose we have graphical objects like buttons, scrollbars,
textfields, canvas, radio buttons and the like.
Suppose each is derived from a superclass class component, which
has a paint method.
Suppose each graphical object overrides the paint method, saying
how it should be drawn on display.
Suppose we have a method update() which has a container for
all the objects on display and simple calls paint on each of them.
Notice how easy it will be to add a new graphical object.
This is how Applet draw on the screen.
What have we accomplished?
- guaranteed that all implementation of shape have area function,
otherwise compile-time error.
- allowed for uniform determination of area via polymorphism,
e.g. we could have a vector of shapes which was a mixture of
rectangles, squares, and circles and we could loop through them
and determine each objects area. But remember we need to cast them
The boundaries of accessibility are determined by class, subclass
and package. If you write your code(classes) in one directory, then the
classes are all part of the same anonymous package.
- Public means accessible to anyone.
- Private means accessible only to members of the class
or to its inner classes.
- No designation means package or friendly accessibility,
ie. full visibility of methods and data to anyone in the same package.
- Protected means accessible to subclasses
and to package members.
- Private Protected means accessible only to subclasses.
- Note: when you subclass and override, you cannot increase the
accessibility. This would lead to a compile error.