Document 7841666

Download Report

Transcript Document 7841666

Applying Inheritance to Solve problems

Designing with inheritance (c) Eraj Basnayake 1

Applied Inheritance

Decide on the classes involved from the problem description

Group classes into

conceptually equivalent

groups

Per group of classes, the generalizing concept will be a Parent to those classes

Distribute responsibilities amongst

all classes based on what is appropriate

and customary for that class. Example A program to teach geometry needs to model some basic shapes. All shapes have surface area, could have volume and location. The shapes that need to be modeled are: Circle, Rectangle, Sphere, Cylinder, and a Square.

What classes will you need? Draw an UML diagram showing class relationships if any.

Designing with inheritance (c) Eraj Basnayake 2

Example

Classes: Circle, Rectangle, Sphere, Cylinder, Square, Coordinate Group classes

All “Shapes”

2D Shapes Circle Rectangle Sphere Cylinder Coordinate Square 3D Shapes Square is a Rectangle Inheritance hierarchy Shape Circle 2D Shapes Rectangle 3D Shapes Cylinder Sphere Square

Designing with inheritance (c) Eraj Basnayake 3

Example…

Shape Circle Shapes2D Rectangle Shapes3D Cylinder Sphere Square Distribute Responsibilities: Shape +getSurfaceArea() +clone() +equals() +toString() +Object getLocation() Shape2D + ?

Shape3D +getVolume() Is Shape2D needed?

Designing with inheritance (c) Eraj Basnayake 4

Example … Abstract classes.

public

abstract

class Shape{ public

abstract

double getSurfaceArea(); public

abstract

Object getLocation(); public

abstract

Object clone(); public

abstract

String toString(); public

abstract

boolean equals(); Observe the syntax of Shape.

The methods are not empty methods }

Abstract Class:

A class with

at least one

unimplemented method.

Shape above is an example of an Abstract class.

Interface:

A class with

only

unimplemented methods.

} public

interface

Shape{ public double getSurfaceArea(); public Object getLocation(); public Object clone(); public String toString(); public boolean equals();

Designing with inheritance (c) Eraj Basnayake 5

Abstract Classes

• • • • • An

abstract class

is a

placeholder

– It is too generic to be of use by itself. – It is used in a class hierarchy to organize common features at appropriate levels.

Abstract class

cannot be instantiated

– However an abstract class variable can reference any concrete derived object.

An

abstract method

has no implementation, just a signature

– It is never intended to be called directly (a

placeholder

).

– Abstract methods can appear only in classes that themselves been declared abstract

The modifier

abstract

is used to define abstract classes & methods

The children of the abstract class are expected to define implementations for the abstract methods in ways appropriate for them

􀂋If a child class does not define all abstract methods of the parent, then the child is also abstract!

Designing with inheritance (c) Eraj Basnayake 6

Interfaces vs Abstract classes, how to decide?

Not all programming languages have Interface’s!

… Regular Class Abstract class Interface So why have abstract classes and interfaces?

To enforce design conformity.

Clients can expect a uniform set of methods for related classes.

Interface’s are used to “tag” a class with a property. While interfaces

are classes

, they represent “action ideas”, “verbs” or “properties” about class.

Designing with inheritance (c) Eraj Basnayake 7

Interfaces...

Sample Interface’s: Cloneable, Drawable, Colorable, Runable, Comparable, … Q: How do you inherit from an interface?

A: By

implement

’ing the interface.

extends

public interface Shape

implements

Cloneable{ … } } public abstract class Shape2D

implements

Shape{ … Q: How do you inherit from an Abstract class?

A: The usual way, by

extend

’ing

} public class Circle

extends

Shape2D{ …

Designing with inheritance (c) Eraj Basnayake 8

Its all still inheritance!

public

interface extends

Shape

implements

Clonable{ … } } public

abstract

class Shape2D

implements

Shape{ … } public

class

Circle

extends

Shape2D{ Circle

has to

unimplemented methods of

2DShape

Shape

Clonable implement

all

Client Code … Circle c = new Circle(); … Shape s = c; Cloneable cln = s; Shape2D s2d = (Shape2D)s;

Designing with inheritance (c) Eraj Basnayake 9

Its all still inheritance!

Client Code … Circle c = new Circle(); … Shape s = c; Cloneable cln = s; Shape2D s2d = (Shape2D) s; through c you can access ALL methods of Circle AND its parents!

Through s you can access ONLY methods of Shape and Cloneable implemented in Circle Through cln you can access ONLY methods of Cloneable implemented in Circle Through s2d you can access ONLY methods of Shape, Cloneable, and Shape2D implemented in Circle.

Designing with inheritance (c) Eraj Basnayake 10

Multiple Inheritance

Some programming languages allow for multiple inheritance.

In Java: Can have multiple interface implementation .

Single inheritance. Types of possible inheritance:

An interface can inherit from multiple interfaces by implementing

A class (abstract or otherwise) can inherit from multiple interfaces by implementing

A class (abstract or otherwise) can inherit from a single other (abstract or normal) class.

Designing with inheritance (c) Eraj Basnayake 11

A harder Example

A Stack Machine is a device that lets you write simple programs that use a Stack. Items (in our example numbers) are placed on and removed from the stack using two commands “push” to place on, and “pop” to take off.

Items are always placed on top of the stack and taken off the top of the stack.

A stack is a last-in-first-out structure. Arithmetic operations can be performed by assuming that the two operands needed for the operation will be the top two items on the stack and the answer will be placed back on the stack.

push 5 push 10 add 10 5 5 15 Stack Stack Stack Any mathematical expression can be converted into a series of machine instructions.

push 5 push 4 5 + (6 * (5 - 4)) subtract push 6 multiply push 5 add

Designing with inheritance (c) Eraj Basnayake

print

12

Example…

What are the classes?

Clients view: public static void main(String[] args){ StackMachine sm = new StackMachine(); sm.load(“programFileName”); sm.run(); } StackMachine

Coordinate all operations.

void load(String fileName) void run() ProgramLoader

Its purpose is to read the program in.

void load(String filename) void String getInstruction(int i) int numInstructions()

Designing with inheritance (c) Eraj Basnayake

Stack

Its purpose is to model the Stack idea.

void push(double value) double pop()

13

Example… gaining an understanding

public class StackMachine{ ProgramLoader pl; Stack stack; public StackMachine(){ pl = new ProgramLoader(); stack = new Stack(); } public void load(String fileName){ pl.load(fileName); } public void run(){ String instruction; for(int i=0; i

push 5 push 4 subtract push 6 multiply push 5 add print Client code public static void main(String[] args){ StackMachine sm = new StackMachine(); sm.load(“example.stk”); sm.run(); }

What happens here?

Designing with inheritance (c) Eraj Basnayake 14

Example… implementing the instructions - one solution

public class StackMachine{ … public void run(){ String instruction; for(int i=0; i

Designing with inheritance (c) Eraj Basnayake

Messy, long, yuck, …

15

Example… another way

Think of instruction as “classes” and group them Organized by number of parameters push pop divide add subtract multiply print one parameter instruction Organized by function instructions no parameter instruction stack arithmetic instructions instructions instructions push multiply add divide subtract pop print

Designing with inheritance (c) Eraj Basnayake

utility instructions

16

Example… another way

OneParameterInstruction Instruction OneParameterInstruction push print pop add multiply divide subtract StackInstruction push pop Instruction ArithmeticInstruction add subtract divide multiply UtilityInstruction print

• •

Each instruction will know how to “execute” itself Each instruction will know how to initialize itself.

Designing with inheritance (c) Eraj Basnayake 17

Example… another way

public interface Instruction{ public void load(StringTokenizer); public void execute(Stack); } public abstract class ArithmeticInstruction implements Instruction{ public void load(StringTokenizer st){} } public class Add extends ArithmeticInstruction{ public void execute(Stack stack){ double operand1 = stack.pop(); double operand2 = stack.pop(); stack.push(operand1+operand2); } }

Designing with inheritance (c) Eraj Basnayake

Quick Review What’s going on?

… Add a = new Add(); Instruction i = a; i.load(st); i.execute(stack);

18

Example… another way

public interface Instruction{ public void load(StringTokenizer); public void execute(Stack); } public abstract class StackInstruction implements Instruction{ //only here for design completeness } public class Pop extends StackInstruction{ public void load(StringTokenizer st){} public void execute(Stack stack){ stack.pop(); } } public class Push extends StackInstruction{ double value; public void load(StringTokenizer st){ String parameter = st.nextToken(); value = Double.parseDouble(parameter); } public void execute(Stack stack){ stack.push(value); } }

Designing with inheritance (c) Eraj Basnayake 19

Example… another way

Will this work?

Is it any better?

Designing with inheritance (c) Eraj Basnayake

common code!

20

Example… another way

Will this work?

public class StackMachine{ … public void run(){ String instruction; for(int i=0; i

Push p = new Push();

}else if (command.toUpperCase().equals(“SUBTRACT”)){

Subtract p = new Subtract();

}else if … …

p.load(st); p.execute(stack);

Common code factored out.

} }

Designing with inheritance (c) Eraj Basnayake

Will this work?

Why or why not?

21

Example… another way

Will this work?

public class StackMachine{ … public void run(){ String instruction; for(int i=0; i

Instruction p;

if (command.toUpperCase().equals(“PUSH”)){

p = new Push();

//upcast }else if (command.toUpperCase().equals(“SUBTRACT”)){ } …

p = new Subtract();

//upcast

p.load(st); p.execute(stack);

//method overriding //method overriding }//for } }

Designing with inheritance (c) Eraj Basnayake 22

Example… another way

public class StackMachine{ … public void run(){ String instruction; for(int i=0; i

Instruction instRef = (Instruction) (Class.forName(command)).newInstance(); instRef.load(st); instRef.execute(stack); }catch(Exception e){ System.out.println(“Syntax error - bad instruction”); System.exit(0); Client code } public static void main(String[] args){ StackMachine sm = new StackMachine(); sm.load(“example.stk”); sm.run(); }

Designing with inheritance (c) Eraj Basnayake 23