Title: Dynamic and Distributed Scheduling in Communication Networks and Manufacturing Systems
1Applying Inheritance to Solve problems
2Classification, Generalization and Specialization
- Classification
- the act of identifying and categorizing similar
objects into classes is known as classification - the resulting categories are known as classes
which form meaningful abstractions for organizing
information
List of people objects in a furniture shop
3Classification, Generalization and Specialization
4Classification, Generalization and Specialization
- Generalization
- generalization is the act of capturing
similarities between classes and defining the
similarities in a new generalized class - the original classes are known as subclasses, and
the generalized class is known as superclass
Employee
superclass
5Classification, Generalization and Specialization
- Specialization
- specialization is the act of capturing
differences among objects in a class and creating
new distinct subclasses with the differences
PeopleInFS
Employee
subclass
6Classification, Generalization and Specialization
- Super- and sub-classes can be organized into a
class hierarchy with the superclasses placed
toward the top of the hierarchy and the
subclasses toward the bottom of the hierarchy - which class an object is referred to in a class
hierarchy is a matter of generality
superclass
PeopleInFS
superclass and subclass
Customer
Employee
SalesPerson
Manager
Secretary
subclass
7Inheritance Example People in Furniture Shop
name getName( )
PeopleInFS
name address budget getName( ) getBudget(
) placeOrder( )
name employeeNum getName( ) getEmployeeNum()
Customer
Employee
name employeeNum commission getName(
) getEmployeeNum( ) getCommission( ) takeOrder( )
SalesPerson
Manager
Secretary
8Inheritance Example People in Furniture Shop
PeopleInFS
- name String getName( ) String
inherits from (or is-a )
Customer
Employee
- address String - budget int getBudget( )
int placeOrder( ) void
- employeeNum int getEmployeeNum( ) int
SalesPerson
Manager
Secretary
- commission int getCommission( )
int takeOrder( ) int
- allowance int getAllowance( ) int
9Inheritance Example People in Furniture Shop
SalesPerson
Employee
getCommission( ) int takeOrder( ) int
PeopleInFS
getName( ) String
- name String
getEmployeeNum( ) int
- employeeNum int
- commission int
10Inheritance and Java Classes/Interfaces
subclass or derived class
superclass or base class
extends
extends
subinterface
superinterface
implements
class
interface
11Applied 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?
12A Geometry Example
Classes Circle, Rectangle, Sphere, Cylinder,
Square, Coordinate
All Shapes
2D Shapes
Circle
Sphere
Coordinate
Rectangle
Group classes
Cylinder
Square
Square is a Rectangle
3D Shapes
Inheritance hierarchy
13A Geometry Example
Distribute Responsibilities
Shape getSurfaceArea() clone() equals() toStr
ing() Object getLocation()
Shape3D getVolume()
Shape2D ?
Is Shape2D needed?
14Example Abstract classes
public abstract class Shape double
getSurfaceArea() Object getLocation()
Object clone() String toString()
boolean equals()
Observe the syntax of Shape The methods are not
virtual methods
- Abstract Class A class with at least one
unimplemented method - Interface A class with only unimplemented methods
.
public interface Shape double
getSurfaceArea() Object getLocation()
Object clone() String toString()
boolean equals()
15Sample Interfaces
Q How do you inherit from an interface? A By
implementing the interface
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 extending
public class Circle extends Shape2D
16Its All Still Inheritance!
public interface Shape extends Clonable
public abstract class Shape2D implements
Shape public class Circle extends
Shape2D
- Circle has to implement all
- unimplemented methods of
- 2DShape
- Shape
- Clonable
17Its All Still Inheritance!
Client Code Circle c new Circle() Shape s
c Cloneable cln s Shape2D s2d 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
18The Class Rectangle
public class Rectangle extends Shape2D private
int width,length public Rectangle(int w,int
l) width w length l public
int getSurfaceArea() return(widthlength)
19The Class Rectangle
public boolean equals(Object o) if(!o
instanceOf Rectangle) return false
Rectangle r (Rectangle)o if (this.width !
r.width) return false if
(this.length!r.length) return false
return true
20The Class Rectangle
public void toString() System.out.println(Rect
anglewidth length) public Object
clone() return(new Rectangle(width,length) p
ublic Object getLocation()
21The Class ShapePair
public abstract class ShapePair extends Shape
private Shape shape1,shape2 public
ShapePair(Shape s1,Shape s2) shape1 s1
shape2 s2 public int getSurfaceArea()
return(shape1.getSurfaceArea()
shape2.getSurfaceArea())
22The Class Rectangle
public Object clone() Shape s1
(Shape)shape1.clone() Shape s2
(Shape)shape2.clone() return(new
ShapePair(s1,s2)
- A very simple example of grouping two shapes!
23Understanding Polymorphism
- Static vs dynamic binding
- binding refers to the association of a method
invocation and the code to be executed on behalf
of the invocation - in static binding, all the associations are
determined at compile time - conventional function calls are statically bound
- char shapeTypenumShapes
- struct circle circlesnumCircles
- struct square squaresnumSquares
- int c 0, s 0
- ...
- for (i 0 i lt numShapes i)
- switch (shapeTypei)
- c calculateCircleArea(circlesc) break
- s calculateSquareArea(squaress) break
-
24Understanding Polymorphism
- in dynamic binding, the code to be executed in
response to a method invocation (i.e., a message)
will not be determined until runtime - method invocations to variable shapeArray (in the
following example) are dynamically bound
public class ShapeDemoClient public static
void main(String argv ) Circle c1 new
Circle("Circle C1") Circle c2 new
Circle("Circle C2", 3.0f) Square s1 new
Square("Square S1") Square s2 new
Square("Square S2", 3.0f) Shape shapeArray
c1, s1, c2, s2 for (int i 0 i lt
shapeArray.length i)
System.out.println("The area of "
shapeArrayi.getName( ) " is "
shapeArrayi.calculateArea( ) " sq. cm.")
// End main // End ShapeDemoClient1 class
25Avoid Confusion Between Is-A and Has-A
- Improper class hierarchies are commonly created
when designers confuse is-a with has-a - is-a relation the extension creates a new
class that is kind of the original class, e.g, - has-a relation an object of one class uses
objects of other classes to store state or do
work - A vehicle is-a Movable Abstraction
- A vehicle is-a Physical Abstraction
- A vehicle has-a location
- A vehicle is-not-a Point (the class of location)
Rectangle
Square
1
circle
point
26Composition versus Inheritance
- All aspects of the protocol are part of childs
interface - Requires us to explicitly send messages to the
class - Restricts operations on child to those that are
applicable - Creates an independent type
- Makes the use of the parent structure an
implementation detail that can easily be changed
- Requires us to look at the parents as well as
childs protocol - Reuses the parents code with no explicit
references - Allows all the parent operations to be applied,
even those that are meaningless for the child - Allows us to use the child anywhere the parent
can be used - Ties the child to choice of the parent structure
27BankAccount hierarchy
We will write thisclass later
Object
BankAccount
JointBankAccount
Every Java class inherits from the top level
Object class.The Object class is the ultimate
parent of every Java class
28BankAccount Examples
- Declare two accounts
- BankAccount fred new
- BankAccount(123, "Fred", 345.50)
- JointBankAccount fredMary new
- JointBankAccount(345, "Fred", "Mary", 450,65)
- A joint account is a type of account
- BankAccount ellenFrank new
- JointBankAccount(456, "Ellen", "Frank", 3450)
- The following statement is illegal
- JointBankAccount fred new
- BankAccount(123, "Fred", 345.50)
29BankAccount Examples
- Consider the two accounts
- JointBankAccount fredMary new
- JointBankAccount(345, "Fred", "Mary", 450,65)
- BankAccount ellenFrank new
- JointBankAccount(456, "Ellen", "Frank", 3450)
- The following statements are legal
- String owner fredMary.getOwner()
- String jointOwner fredMary.getJointOwner()
- The 2nd statement is illegal
- String owner fredMary.getOwner()
- String jointOwner ellenFrank.getJointOwner()
30AccountReader Example
- Problem Write an AccountReader class that can
read both BankAccount and JointBankAccount
objects. - Suggests that we need two methods with prototypes
- public BankAccount readBankAccount()
- public JointBankAccount readJointBankAccount()
- Because of polymorphism only the first version is
needed a joint account "is an" account.
31AccountReader Example
- package booklib
- import booklib.BankAccount
- import booklib.JointBankAccount
- import booklib.KeyboardReader
- public class AccountReader
-
- private KeyboardReader input
- new KeyboardReader()
- public BankAccount readAccount() ...
32AccountReader Example
- public BankAccount readAccount()
-
- // declare local vars
- // read account type
- // read number, balance, owner
- if (type 2)
-
- // read joint owner name
- return new JointBankAccount(...)
-
- else
- return new BankAccount(...)
it's also aBankAccount
33AccountReaderTester
- import booklib.
- public class AccountReaderTester
-
- public AccountReaderTester()
-
- AccountReader accountInput new
- AccountReader()
- BankAccount a accountInput.readAccount()
- System.out.println(a)
-
- public static void main(String args)
- new AccountReaderTester()
-
34toString is polymorphic
- The print statement System.out.println(a)is
shorthand for System.out.println(a.toString())
- the Java run-time system knows whether a refers
to a BankAccount object or to a JointBankAccount
object so it calls the correct version of the two
toString methods
35Bank Account Processing
- Problem Read an array of BankAccount objects and
process them in several ways. - Reading the array is common to all processors
- Therefore we start with an abstract account
processor class that has a non-abstract method to
do the account reading and provides an abstract
method for account processing - Each subclass will provide its own implementation
of the processor method.
36AccountProcessor
- abstract public class AccountProcessor
- private AccountReader inputAccount
- new AccountReader()
- protected KeyboardReader console
- new KeyboardReader()
- protected BankAccount account
- public void readAccounts()...
-
- abstract public void processAccounts()
subclasses willneed to accessthem
semi-colonis necessary
keyword to indicate abstract classes and methods
37readAccounts Method
- public void readAccounts()
-
- System.out.println("How many accounts?")
- int size input.readInt()
- account new BankAccountsize
- for (int k 0 k lt account.length k)
-
- accountk inputAccount.readAccount()
-
38MaxBalanceProcessor
- public class MaxBalanceProcessor
- extends AccountProcessor
-
- public void processAccounts()
-
- double max account0.getBalance()
- for (int k 1 k lt account.length k)
-
- double b accountk.getBalance()
- if (b gt max) max b
-
- System.out.println
- "The maximum balance is " max)
-
implement theprocessAccountsmethod
39MaxBalanceProcessorRunner
- public class MaxBalanceProcessorRunner
-
- public static void main(String args)
-
- MaxBalanceProcessor program
- new MaxBalanceProcessor()
- program.readAccounts()
- program.processAccounts()
-
calls method inAccountProcessor
40A Fund Transfer Method
- Problem Write a method that can be used to
transfer a given amount from one bank account to
another that works with both BankAccount and
JointBankAccount objects - Without polymorphic types we would need four
different methods to cover the four possible
types of transfer (bank to bank, joint to joint,
bank to joint and joint to bank) - With polymorphism only one method is needed
41A Fund Transfer Method
- public void transfer(BankAccount from,
- BankAccount to, double amount
-
- boolean ok from.withdraw(amount)
- if (ok)
-
- to.deposit(amount)
-
-
- This works because a JointBankAccount "is a"
BankAccount
42Using the Method
- BankAccount fred new BankAccount(...)
- BankAccount joan new BankAccount(...)
- JointBankAccount fredMary
- new JointBankAccount(...)
- JointBankAccount joanBob
- new JointBankAccount(...)
- transfer(fred, joan, 89.55)
- transfer(fred, fredMary, 49.35)
- transfer(joanBob, fredMary, 100.00)
- transfer(joanBob, joan, 50.00)
43Employee Hierarchy
Everything commonto all employees
Employee
Manager
HourlyWorker
PartTimeWorker
These differ onlyin how the salaryis calculated
CommissionWorker
44Abstract Employee Class
- abstract public class Employee
-
- private String name
- public Employee(String name)
- this.name name
-
- public String getName()
- return name
-
- abstract public double grossSalary()
- abstract public double netSalary()
Constructor forthe name part
polymorphicmethods
45Subclasses
- Manager
- gross monthly salary,10 deductions.
- HourlyWorker
- gross monthly salary from hours worked and hourly
wage, 5 ideductions. - PartTimeWorker
- as above with not deductions
- CommissionWorker
- like manager with a commission as a percentage of
monthly sales
46The Manager Class
- public class Manager extends Employee
-
- protected double gross
- protected double net
- public Manager(String name, double salary)
-
- super(name)
- gross salary
- net 0.9 gross
-
- public double grossSalary() return gross
- public double netSalary() return net
- public String toString() ...
call superclassconstructor todo its part
47ProcessEmployees
- public Employee staff
- ...
- public void doCalculations()
- totalGrossSalary totalNetSalary 0.0
- for (int k 0 k lt staff.length k)
-
- totalGrossSalry staffk.grossSalary()
- totalNetSalary staffk.netSalary()
- System.out.println(staffk)
-
- totalBenefits
- totalGrossSalary - totalNetSalary
a polymorphic loop
48What is an Adapter Class?
- Inheritance always adds functionality.
- Sometimes we need to subtract functionality.
- For example we may want to make a class serve a
more specific or simpler purpose by hiding some
of its methods. - Adapter classes use composition to do this.
- Our custom format class is an example hiding the
complexity of the DecimalFormat class.
49The java.util.Vector class
- This is a generic dynamic container class. Some
of its constructors and methods are - public Vector()
- public Vector(int initialCapacity)
- public void addElement(Object obj)
- public Object elementAt(int k)
- public void setElementAt(int k)
- public int size()
- // convert vector to an Object array
- public Object toArray()
- // convert to array of specified type
- public Object toArray(Object obj)
50Vector with BankAccount
- Storing BankAccount objects in a Vector container
- Vector v new Vector()
- v.addElement(new BankAccount(123,"Fred",345.50)
- v.addElement(new BankAccount(345,"Mary",435.43)
- System.out.println(v.elementAt(0))
- System.out.println(v.elementAt(1))
- BankAccount b (BankAccount) v.elementAt(0)
Object amnesiaagain
51Vector with BankAccount
- Converting a Vector to an array
- Vector v new Vector(1000)
- ...
- BankAccount a new BankAccountv.size()
- a (BankAccount) v.toArray(a)
Object amnesiaagain
52BankAccountVector Class
- package booklib
- import java.util.Vector
- public class BankAccountVector
-
- private Vector v // composition (hide it)
- public BankAccountVector() ...
- public BankAccountVector(int initialCap)...
- public void addAccount(BankAccount b) ...
- public BankAccount getAccount(int k) ...
- public void replaceAccount(BankAccount b,
- int k) ...
- public int size() ...
- public BankAccount toArray() ...
53BankAccountVector Class
- Constructors
- public BankAccountVector()
-
- v new Vector()
-
- public BankAccountVector(int initialCap)
-
- v new Vector(initialCapacity)
54BankAccountVector Class
- Methods
- public void addAccount(BankAccount b)
-
- v.addElement(b)
-
- public BankAccount getAccount(int k)
-
- return (BankAccount) v.elementAt(k)
55BankAccountVector Class
- Methods
- public void replaceAccount(BankAccount b, int k)
- v.setElementAt(b,k)
-
- public int size()
- return v.size()
-
- public BankAccount toArray()
- BankAccount b new BankAccountv.size()
- return (BankAccount) v.toArray(b)
56A 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
57A Harder Example
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))
58A Harder Example
public static void main(String args)
StackMachine sm new StackMachine()
sm.load(programFileName) sm.run()
Clients view
What are the classes?
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()
Stack Its purpose is to model
the Stack idea void push(double value) double
pop()
59Example 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 i0 iltpl.
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?
60Implementing the instructions First Solution
public class StackMachine ... public void
run() String instruction for(int
i0 iltpl.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,
61Implementing the instructions Better Solution
- 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
utility instructions
print
62Implementing the instructions Better Solution
Instruction
OneParameterInstruction
NoParameterInstruction
push
pop
add
multiply
divide
subtract
print
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
63Implementing the instructions Better Solution
public class StackMachine ... public void
run() String instruction for(int
i0 iltpl.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)
Client code public static void main(String
args) StackMachine sm new StackMachine()
sm.load(example.stk) sm.run()
64Implementing the instructions Better Solution
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(operand1operand2)
65Implementing the instructions Better Solution
public interface Instruction public void
load(StringTokenizer) public void
execute(Stack)
public abstract class StackInstruction implements
Instruction // only here for design
completeness
public class PopInstruction extends
StackInstruction public void
load(StringTokenizer st) public void
execute(Stack stack) stack.pop()
public class PushInstruction extends
StackInstruction double value public void
load(StringTokenizer st) String parameter
st.nextToken() value Double.parseDouble(par
ameter) public void execute(Stack stack)
stack.push(value)