Construction of classes with classes
Classes can be built on existing classes through attributes of object types. Example:
I A classPairOfDice can be constructed using two attributes of the
typeDice.
I A classCardDeckcan be build with the help of an array of an object array containing 52 objects of the typeCard
I A classListMapcan be constructed with the help of ListNodeobjects
I A classTrafficSystemcan be constructed using objects from the classesLane,Light,Vehicle. . .
Class hierarchies
A new class can also be built as a specialization of an existing class. Example:
I The class StackExceptionthat is used in the Stack class is written as a sub class toException
I If we have a classVehicle, we can build new classes likeSegway,
BicycleandCar. ACarcan in turn be a base class for the classes
Private car andTruck
Segway Bicycle Car
Private Car Truck
In these cases you say that you have a class hierarchy
I The class Vehicleis called a base class
I The classesSegway,BicycleandCarare derived classes or sub classes to the classVehicle
I A subclass (e. g. the classCar) can be used as a base class for other classes (e. g. Private car andTruck)
One use to say the the phrase is a ... that ...
Inheritance
An object of a sub class
I has all the attributes and methods of the base class and I can add more by itself
One say that the sub class inherits all the characteristics of the base class. Example: The class Carcan have the attributeweight. A Private car can addnPassenger while aTruck can addmaxLoad.
Unied Modeling Language (UML)
The class hierarchies are often express in class diagrams in UML.
print() : void print() : void print() : void maxLoad : double print() : void nPassenger : int print() : void Segway Vehicle Bicycle Car Truck Private Car weight : double
The Vehicle hierarchy in code
public class Vehicle {public void print() {
System.out.print("Vehicle"); }
}
public class Segway extends Vehicle { } public class Bicycle extends Vehicle {
public void print() {
System.out.print("Bicycle"); }
}
public class Car extends Vehicle { double weight;
public Car( double v ) { weight = v;
}
Usage
The code
...
public static void pr(String s) { System.out.print(s);
}
public static void main(String [] args) { Vehicle f = new Vehicle();
Segway s = new Segway(); Bicycle c = new Bicycle(); Car b = new Car(1.2); pr("f: "); f.print(); pr("\n"); pr("s: "); s.print(); pr("\n"); pr("c: "); c.print(); pr("\n"); pr("b: "); b.print(); pr("\n"); ...
give the printout
f: Vehicle s: Vehicle c: Bicycle
More subclasses
public class PrivateCar extends Car { int nPassenger = 5;
public PrivateCar(double v) { super(v);
}
public PrivateCar(double v, int ant) { super(v);
nPassenger = ant; }
public void print() {
System.out.print("Private"); super.print();
System.out.print(", number of passengers " + nPassenger); }
Continuation of
main...
PrivateCar pb1 = new PrivateCar(1.5); PrivateCar pb2 = new PrivateCar(0.9,4); pr("pb1: "); pb1.print(); pr("\n"); pr("Weight b : " + b.weight + "\n"); pr("Weight pb1: " + pb1.weight + "\n"); f = b; pr("f: "); f.print(); pr("\n"); f = pb1; pr("f: "); f.print(); pr("\n"); pb1 = (PrivateCar) f; pr("pb1: "); pb1.print(); pr("\n");
gives the printout
pb1: PrivateCar, weight 1.5 and number of passengers 5 Weight b: 1.2
Weight pb1: 1.5 f: Car, weight 1.2
f: PrivateCar, weight 0.9 and number of passengers 4 pb1: PrivateCar, weight 0.9 and number of passengers 4
Example of illegal operations
pb1 = f;
pb1 = (PrivateCar) c; pr("Weight: " + f.weight);
pb1 = (PrivateCar) f; // if f don't refer a PrivateCar
The last can be made safe through
if ( f instanceof PrivateCar ) pb1 = (PrivateCar) f; else
...
Conclusions
If the class Sis a subclass of the classBand if s is declared as a reference to Sandbto Bwe have
I An object of the classShas all attributes and methods that the classB
have
I If Sdeclares an attribute that are declared B, that attribute is overridden byB's attribute.
I A reference can refer objects of the declared class and its subclasses. I The construction b.x(orb.x()) requires that the attribute (or
method)xis declared in Bor any of B'sbaseclasses.
I When you use an attributea through dot notationp.a, it is the declaration of pthat settles what attributes are used.
I When you call a method musingp.m(), it is the type of the element thatp refers that settles what method is selected. (so called dynamic or late binding).
Methods that only are declared in selected classes
Private Car nPassenger : int print() : void tax() : double print() : void Segway Vehicle Truck maxLoad : double print() : void tax() : double Bicycleprint() : void weight : double print() : void
Car
Cars are taxed, but the calculations are done in dierent way for private cars and trucks.
Usage of the
tax-method
Car b = new Truck(3., 2.); ... if (...) { b = new PrivateCar(1.2, 5); } ... double s;
s = b.tax(); // Illegal! No tax in b s = ((Truck) b).tax(); // Risky!
if ( b instanceof Truck ) // Works but clumsy s = ((Truck) b).tax(); // and inflexible else if ( b instanceof PrivateCar )
s = ((PrivateCar) b).tax(); else
Better
Dene also a methodtax-method in the classCaror, better, in the class
Vehicle: Private Car nPassenger : int print() : void tax() : double Vehicle Bicycle tax() : double Truck maxLoad : double print() : void tax() : double Segway
print() : void weight : double print() : void
Car
print() : void
public class Vehicle { public void print() {
System.out.print("Vehicle"); }
public double tax() { return 0;
} }
Then the method can be used for all objects of the type Vehicleor its sub classes.
Levels of protection
I private
Only accessible from the classes own methods
I public
Accessible for all
I protected
Accessible from subclasses and classes in the same package
I package
If no level of protection is given. all classes are assigned package access level
Constructors in inheritance
Constructors are not inherited
When an object of a subclass is created, the following steps are taken: 1. Instance variables take their default values
2. A constructor for the base class (super class) is called. You use the keyword superto specify which constructor in the base class that should be used. If superis not used, the parameterless constructor in the base class are used, in this case there has to exist such a
constructor.
3. If there are initializarions they are evaluated and assigned to the respective attributes.
Standard software in Java
The Java environment is based on inheritance and class hierarchies! Example:
1. The classes for exceptions: Throwablewith the subclassesErrorand
Exceptionwith the subclasses . . .
2. Graphical components: Componentwith subclassesButton,Checkbox,
Container, . . . where e. g. Containerhas the subclassesPanel,
Window. . .
3. Maps: Mapwith (among others) the subclasss HashMap
4. The Collection classes: Collection with (among others) the subclass
List that have the subclassesVectorandLinkedList
The Class
ObjectThe class Object is the baseclass to all classes. A reference to Objectcan thus refer any object.
This can be used to construct general collection classes (lists, tables or . . . ): class ListNode { Object info; ListNode next; ListHead(Object i, ListNode n) { info = l; next = n; } }
public class List { ListNode head;
public void insertFirst(Object o) { head = new ListNode(o, head) }
... }
The class
Objectcont
Some methods in the class Object:
I Object clone()
I boolean equals(Object o)
I String toString()
An example of using inheritance: geometrical gures
Write a program that can handle pictures of circles, rectangles and other geometrical shapes.
The program should be able to
I represent a number of dierent shapes. I Draw an image of the represented shapes. I Compute the accumulated area of all gures. I Read rules about the structure of a certain shape.
Cont geometrical gures
1. Which classes are needed to represent the gures? Circle, Rectangle, . . .
2. What attributes and methods should we have?
I constructors
I methods for calculating areas I methods for drawing
3. How should one represent a collection of such gures?
I array? I list?
I other structure?
Cont geometrical gures
paint():void Rectangle Circle radius: int area() : double height : int area(): double paint():void paint():void Shape width : int xCoord : int yCoord : int area() : doubleCont geometrical gures
Now we can e. g. do
Shape[] fig = new Shape[100]; fig[0] = new Rectangle(...); fig[1] = new Circle(...); ...
(but we are to use a more exible structure than an array)
There is no meningful implementation of area() andpaint()in Shape! Declare these methods and the class Shapeas abstract.
Cont geometrical gures
import java.awt.*;public abstract class Shape { protected int xCoord, yCoord; public Shape(int x, int y) {
xCoord = x; yCoord = y; }
public abstract double area();
public abstract void paint(Graphics g); }
Cont geometrical gures
import java.awt.*;public class Circle extends Shape { protected int radius;
public Circle(int x, int y, int r){ super(x,y);
radius = r; }
public double area(){
return Math.PI*radius*radius; }
public void paint(Graphics g){ g.setColor(Color.RED);
g.fillOval(xCoord-radius, yCoord-radius, 2*radius, 2*radius); }
Cont geometrical gures
import java.awt.*;public class Rectangle extends Shape { protected int width, height;
public Rectangle(int x, int y, int w, int h) { super(x,y);
width = w; height = h; }
public double area(){ return width*height; }
public void paint(Graphics g){ g.setColor(Color.BLUE);
g.fillRect(xCoord,yCoord,width,height); }
Cont geometrical gures
To collect a number of dierent gures we use one of the collection classes in Java: LinkedList that is a (indirect) subclass to Collection (actually an interface).
For this task, it is sucient to
I Crete a LinkedList object:
Collection<Shape> shapes = new LinkedList<Shape>();
I Add gures to the list, e. g.:
shapes.add(new Circle(x,y,r));
I Iterate over the elements and access their methods. E. g:
for (Shape s:shapes) s.paint();
Cont geometrical gures
import javax.swing.*;import java.awt.*; import java.util.*;
public class Drawing extends JPanel { private Collection<Shape> shapes;
public Drawing(Collection<Shape> s, int w, int h) { shapes = s;
setBackground(Color.WHITE);
setPreferredSize(new Dimension(w,h)); }
public double area(){ double a = 0;
for (Shape s:shapes) a += s.area(); return a;
}
public void paintComponent(Graphics g){ super.paintComponent(g);
Cont geometrical gures
import javax.swing.*;import java.awt.*; import java.util.*;
public class DrawTest extends JFrame { public static void main(String[] args){
Collection<Shape> shapes = read(new Scanner(System.in)); Drawing d=new Drawing(shapes,400,400);
System.out.println("Total area: " + (int)d.area()); new DrawTest(d); } public DrawTest(Drawing d){ getContentPane().add(d); pack(); setTitle("DrawTest"); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); }
Cont geometrical gures
private static Collection<Shape> read(Scanner sc){ Collection<Shape> shapes = new LinkedList<Shape>(); while (sc.hasNext()){ String s=sc.next(); if (s.equals("circle")){ int x, y, r; x = sc.nextInt(); y = sc.nextInt(); r = sc.nextInt(); shapes.add(new Circle(x,y,r)); } else { int x, y, w, h; x = sc.nextInt(); y = sc.nextInt(); w = sc.nextInt(); h = sc.nextInt(); shapes.add(new Rectangle(x,y,w,h)); } } return shapes;
Cont geometrical gures
Note how the classes are based on inheritance. They inherit from the graphical classes in Java. Details in graphics are outside the scope of this course.
If you run the program with
java DrawTest < figure.txt
and the lefigure.txt contain
rectangle 20 50 200 30 circle 350 100 30 rectangle 300 200 50 150 circle 100 300 80