Slide1 l.jpg
Advertisement
This presentation is the property of its rightful owner.
1 / 23

Applying Inheritance to Solve problems PowerPoint PPT Presentation

Applying Inheritance to Solve problems 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

Related searches for Applying Inheritance to Solve problems

Download Presentation

Applying Inheritance to Solve problems

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Slide1 l.jpg

Applying Inheritance to Solve problems

Designing with inheritance (c) Eraj Basnayake


Slide2 l.jpg

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 allclasses 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


Slide3 l.jpg

Example

Shape

2D Shapes

3D Shapes

Circle

Rectangle

Sphere

Cylinder

Square

Classes:

Circle, Rectangle, Sphere, Cylinder, Square, Coordinate

Group classes

All “Shapes”

2D Shapes

Circle

Sphere

Coordinate

Rectangle

Cylinder

Square

3D Shapes

Square is a Rectangle

Inheritance hierarchy

Designing with inheritance (c) Eraj Basnayake


Slide4 l.jpg

Example…

Shape

Shapes2D

Shapes3D

Circle

Rectangle

Sphere

Cylinder

Square

Distribute Responsibilities:

Shape

+getSurfaceArea()

+clone()

+equals()

+toString()

+Object getLocation()

Shape3D

+getVolume()

Shape2D

+ ?

Is Shape2D needed?

Designing with inheritance (c) Eraj Basnayake


Slide5 l.jpg

Example … Abstract classes.

public abstract class Shape{

public abstractdouble getSurfaceArea();

public abstractObject getLocation();

public abstractObject clone();

public abstractString toString();

public abstractboolean 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


Abstract classes l.jpg

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


Slide7 l.jpg

Interfaces vs Abstract classes, how to decide?

Not all programming languages have Interface’s!

1 unimplemented

method

2 unimplemented

method

All methods

unimplemented

All methods

implemented

Abstract

class

Interface

Regular

Class

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


Slide8 l.jpg

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


Slide9 l.jpg

Its all still inheritance!

extends

public interface Shape implements Clonable{

}

public abstract class Shape2D implements Shape{

}

public class Circle extends Shape2D{

}

Client Code

Circle c = new Circle();

Shape s = c;

Cloneable cln = s;

Shape2D s2d = (Shape2D)s;

  • Circle has to implement all

  • unimplemented methods of

  • 2DShape

  • Shape

  • Clonable

Designing with inheritance (c) Eraj Basnayake


Slide10 l.jpg

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 CircleAND 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


Slide11 l.jpg

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


Slide12 l.jpg

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

add

push 10

10

15

5

5

Stack

Stack

Stack

Any mathematical expression can be converted into a series of machine instructions.

push 5

push 4

subtract

push 6

multiply

push 5

add

print

5 + (6 * (5 - 4))

Designing with inheritance (c) Eraj Basnayake


Slide13 l.jpg

Example…

Stack

Its purpose is to

model the Stack

idea.

void push(double value)

double pop()

ProgramLoader

Its purpose is to read the

program in.

void load(String filename)

void String getInstruction(int i)

int numInstructions()

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()

Designing with inheritance (c) Eraj Basnayake


Slide14 l.jpg

Example… gaining an understanding

example.stk

push 5

push 4

subtract

push 6

multiply

push 5

add

print

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<pl.numInstructions(); i++){

instruction = pl.get(i);

System.out.println(instruction);

}

}

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


Slide15 l.jpg

Example… implementing the instructions - one solution

public class StackMachine{

public void run(){

String instruction;

for(int i=0; i<pl.numInstructions(); i++){

instruction = pl.get(i);

StringTokenizer st = new StringTokenizer(instruction);

String command = st.nextToken();

if (command.toUpperCase(“PUSH”){

String parameter = st.nextToken();

stack.push(Double.parseDouble(parameter));

}

else if (command.toUpperCase(“PRINT”){

double d = stack.pop();

System.out.println(d);

}

}

}

Messy, long, yuck, …

Designing with inheritance (c) Eraj Basnayake


Slide16 l.jpg

Example… another way

Think of instruction as “classes” and group them

instructions

Organized by

number of parameters

pop

divide

add

push

subtract

print

multiply

one parameter

instruction

no parameter

instruction

Organized by function

arithmetic instructions

instructions

multiply

stack

instructions

divide

add

push

subtract

pop

print

utility

instructions

Designing with inheritance (c) Eraj Basnayake


Slide17 l.jpg

Example… another way

Instruction

OneParameterInstruction

OneParameterInstruction

push

print

pop

add

multiply

divide

subtract

Instruction

ArithmeticInstruction

UtilityInstruction

StackInstruction

push

pop

add subtract divide multiply

print

  • Each instruction will know how to “execute” itself

  • Each instruction will know how to initialize itself.

Designing with inheritance (c) Eraj Basnayake


Slide18 l.jpg

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){}

}

Quick Review

What’s going on?

Add a = new Add();

Instruction i = a;

i.load(st);

i.execute(stack);

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


Slide19 l.jpg

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


Slide20 l.jpg

Example… another way

public class StackMachine{

public void run(){

String instruction;

for(int i=0; i<pl.numInstructions(); i++){

instruction = pl.get(i);

StringTokenizer st = new StringTokenizer(instruction);

String command = st.nextToken();

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

Push p = new Push();

p.load(st);

p.execute(stack);

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

Subtract p = new Subtract();

p.load(st);

p.execute(stack);

}

}

}

}

public class StackMachine{

public void run(){

String instruction;

for(int i=0; i<pl.numInstructions(); i++){

instruction = pl.get(i);

StringTokenizer st = new StringTokenizer(instruction);

String command = st.nextToken();

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

Push p = new Push();

p.load(st);

p.execute(stack);

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

Subtract p = new Subtract();

p.load(st);

p.execute(stack);

}

}

}

}

public class StackMachine{

public void run(){

String instruction;

for(int i=0; i<pl.numInstructions(); i++){

instruction = pl.get(i);

StringTokenizer st = new StringTokenizer(instruction);

String command = st.nextToken();

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

Push p = new Push();

p.load(st);

p.execute(stack);

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

Subtract p = new Subtract();

p.load(st);

p.execute(stack);

}

}

}

}

Will this work?

Is it any better?

common

code!

Designing with inheritance (c) Eraj Basnayake


Slide21 l.jpg

Example… another way

Will this work?

public class StackMachine{

public void run(){

String instruction;

for(int i=0; i<pl.numInstructions(); i++){

instruction = pl.get(i);

StringTokenizer st = new StringTokenizer(instruction);

String command = st.nextToken();

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

Push p = new Push();

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

Subtract p = new Subtract();

}else if …

p.load(st);

p.execute(stack);

}//for

}

}

Common code

factored out.

Will this work?

Why or why not?

Designing with inheritance (c) Eraj Basnayake


Slide22 l.jpg

Example… another way

Will this work?

public class StackMachine{

public void run(){

String instruction;

for(int i=0; i<pl.numInstructions(); i++){

instruction = pl.get(i);

StringTokenizer st = new StringTokenizer(instruction);

String command = st.nextToken();

Instruction p;

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

p = new Push();//upcast

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

p = new Subtract();//upcast

}

p.load(st);//method overriding

p.execute(stack);//method overriding

}//for

}

}

Designing with inheritance (c) Eraj Basnayake


Slide23 l.jpg

Example… another way

public class StackMachine{

public void run(){

String instruction;

for(int i=0; i<pl.numInstructions(); i++){

instruction = pl.get(i);

StringTokenizer st = new StringTokenizer(instruction);

String command = st.nextToken();

try{

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);

}

}

}

}

A really cool way

to do all that!

Client code

public static void main(String[] args){

StackMachine sm = new StackMachine();

sm.load(“example.stk”);

sm.run();

}

Designing with inheritance (c) Eraj Basnayake


  • Login