Vous êtes sur la page 1sur 53

Object Oriented

Design
Introduction
Why worry?
Quick and dirty programs written by one
programmer used by himself
not necessary to create elegant design elaborately
all that is important is that code works correctly
Code that is developed by many developers
in collaboration for long term
used by many people
should be maintainable long term
Why worry? (continued)
Not enough for the program not to have errors/bugs.
Also important that they are maintainable in the
future.
Example is JDK classes.
A poor design will cause problems for the
developers using the classes
If a valuable feature was omitted, developers will
have to write their own code, possibly in an awkward
way.
Why worry? (continued)
In medium to large systems, many developers would
be involved.
no one person may understand the entire code
base.
each programmer would be working on a small
portion of it.
if such a solution is not well designed, a bug
introduced in one module can affect another module
written by other programmers and introduce bugs.
Poor design in large projects
In 1962, the Mariner I spacecraft lifted off to
venus, but was destroyed by the mission control
because a bug in the program incorrectly
reported that the booster rocket malfunctioned.
In 1993, a bug in the SunSoft os held up a $20
million sale. Bug was traced to usage of x==2
instead of x=2.
Measuring quality of a design
Usability
Completeness
Robustness
Efficiency
Scalability
Readability
Reusability
Simplicity
Maintainability
Extensibility
OO Vs. Non-OO Programming
In a structured programming language such as C, global
functions and global data exist.
There is no concept of grouping functions and data
together to create objects.
In C the program is process oriented or data oriented.
In OO languages each object encapsulates a concept.
In OO languages Intelligence (in form of methods) and
knowledge (data) are distributed among the objects.
Advantages of OO Programming
Manageable code.
Modifiability, readability, reusability and maintainability.
Coupling is minimized: changing an internal data
structure for a particular class means only changing that
particular object.
If an object is working inefficiently, only that objects
code needs to be changed.
Classes in Java
public class Person
{
private String name;
private Date birthdate;
public Person(String name, Date birthdate)
{
this.name = name;
this.birthdate = birthdate;
}
public String getName() {
return name;
}
public Date getBirthdate()
{
return birthdate;
}
}
Person class
It has two attributes or fields called name
and birthdate.
It has one constructor.
It has two methods.
firstPerson object
An object is an instance of a Class
In Java, it is created using new keyoword as follows:
Person firstPerson = new Person(Adam, new Date());
A message can be sent to this object as follows:
String firstPersonName = firstPerson.getName();
Methods
In Java passing a message is called method
call on an object.
Can be thought as services provided by
objects of a class to other objects.
Correspond to the behavior of objects of this
class.
Instance Variables/Fields
Data that is needed by the object is stored in
instance variables or fields.
They provide state information for an object.
What distinguishes two objects of the same
class is the state.
Class Variables
State of the class itself.
It is possible to write non-oo code using
these.
Use these with care.
Typical use is constants that are same for all
objects.
Allow all objects to share the same data.
Class Methods
Are useful when:
Objects of a class are stateless.
Some methods do not need state and only
manipulate parameters passed to the method.
For example in Math class all methods are public
static methods.
Choosing between an Object method
and Class Method
Take an example of a Set class and it needs
to have functionality to calculate intersection
of two sets.
It can be defined as follows in two ways:
public Set intersect(Set otherSet);
public static Set intersect(Set firstSet, Set
secondSet);
Choosing between an Object method
and Class Method (continued)
Which design is better?
Advantages of first version:
It is a natural way to proceed from an oo
perspective.
intersect method can be overridden by future users
extending from Set class
Choosing between an Object method
and Class Method (continued)
Which design is better?
Advantages of second version:
It displays a natural symmetry where no set plays a
special role.
need not fail with NullPointerException if s1 or s2
happened to be null
Call to first method can fail even before intersect
method starts executing. Such thing need not
happen with this version.
Few approaches possible to extend
an existing class
If source code for existing class is available, the
programmer could add new functionality to that class.
Alternatively programmer can add entire code into a
new class and add his own code to it and give a new
name to the class.
Another approach is to start from scratch.
Best approach is to derive from the existing class and
add new functionality.
Few approaches possible to extend
an existing class (continued)
In the first approach, there will be two classes with the same name
to confuse both the users of those classes and the compiler.
In the second approach, there is major code duplication which
introduces unnecessary complication.
In the third approach of starting from scratch, no advantage is
taken of an existing code base which may been thoroughly tested
and is bug free.
Neither of these will work if only class file is available and not the
original source code.
Implementation Inheritance
Greatly increases reusability of classes.
Minimizes duplication of Code.
Useful when compiled classes are only
available and we need to extend the
functionality of that class.
Implemented by extends keyword in Java.
Example of inheritance
public class EnhancedRectangle extends Rectangle
{
public EnhancedRectangle(int x, int y, int w, int h) //constructor
{
super(x, y, w, h);
}
public Point getCenter()
{
return new Point((int) getCenterX(), (int) getCenterY());
}
public void setCenter(int x, int y)
{
setLocation( x (int) getWidth()/2, y (int) getHeight()/2);
}
}
Object super class in Java
All classes implicitly extend Object class in
Java.
This means default implementations of
clone, equals, finalize, getClass, hashcode,
notify, notifyAll, toString and three versions
of wait are automatically inherited by any
Java object.
Method overriding
A method implemented in a subclass that has the same
signature as a method implemented in the superclass is said
to override the superclass method.
The signature of a method consists of the method name and
the list of types of the parameters. Return type needs to be
compatible with the return type of overridden method.
In this case new attributes or new methods are not added,
but existing methods are modified to produce changed
behavior.
Generalization
Subclassing and superclassing can be used to avoid
code and data duplication among several classes.
This can be done by creating a superclass to those
classes and moving the duplicate code and data up into
that superclass, which is commonly abstract.
In java the class is prefixed with abstract keyword.
In a UML diagram, the class is marked as abstract by
showing it in italics.
This process is called inheritance for generalization.
Single Inheritance
In Java, only single inheritance is supported.
Inheritance from multiple classes is not
supported.
This is done to avoid some ambiguity that
can occur in multiple inheritance.
Type
A Type can be defined as a set of data values and
operations that can be performed on them.
Two ways to define a Type in Java:
Any Class C and its subclasses in Java form a type
C.
Interface
A class can be of multiple types.
Objects of a subclass S of a class T are considered to
be both of type S and of type T
Interfaces
An interface can be thought of as named set of operations.
All objects whose classes explicitly implement the interface form the set
of objects of that type.
Example:
public interface Runnable
{
public void run();
}
All objects whose classes implement the interface Runnable are of type
Runnable.
Subtypes
If class S is a subclass of class T, S is said to be a
subtype of T. T can also be called supertype of S.
If a class B is a subclass of class A or if B implements
an interface A or if B is a subinterface(extends interface
A) of interface A, then the type B is a subtype of the
type A.
Polymorphism
Allows variable of one type to store an object
of subtype.
The fact that an object of a subtype can be
legally used wherever an object of a
supertype is expected is called subtype
polymorphism.
Value of Polymorphism
Like plug and play hardware, allows plug
and play software components.
An object of one class can be replaced with
object of another equivalent class with
minimal work to code.
Value of Polymorphism (continued)
Take an object that uses a LinkedList object.
Assume that there are performance issues
with LinkedList and it needs to be changed
to a ArrayList for better performance.
Without polymorphism, such change will
involve significant changes to the code base.
Value of Polymorphism (continued)
If the system is not designed with
polymorphism in mind, all occurrences of
LinkedList need to be replaced with
ArrayList.
With polymorphism, List list = new
LinkedList(); needs to be replaced with:
List list = new ArrayList();
Value of Polymorphism (continued)
Thus by polymorphism, we do not need to change
method calls of these variables because these method
calls are that of List interface.
Another better design approach is to define a Manager
class with the following method:
public List createNewList()
{
return new LinkedList();
}
Value of Polymorphism (continued)
And then use :
List list = manager.createNewList();
where manager is an available object of class Manager
With this we simply change the createNewList method
to return ArrayList and everything else will remain same.
Multiple inheritance through
interfaces
In Java, a class can implement as many
interfaces as it needs to.
This does not result in any ambiguity
because we are not inheriting the
implementations of the methods, even
though we implement multiple interfaces.
Interfaces vs. Abstract Classes
Abstract class can implement certain
methods and have instance variables.
Some methods in an abstract class can be
marked as abstract
In the case of interface, all methods are
abstract and no instance variables (except
final constants) are allowed.
Interfaces vs. Abstract Classes
(continued)
When your class needs instance variables to maintain state and yet certain
methods are to be abstract, go for abstract class.
Consider the following:
public abstract class TotallyAbstractClass
{
public abstract void clear();
public abstract void visit(Object o);
}
In this case it is better to go for interface because once a class extends
from this class, it cannot extend from any more classes.
Interfaces vs. Abstract Classes
(continued)
Another way to think about this is that a programmer
typically implements an interface to permit subtype
polymorphism.
In contrast, a programmer extends a class as a way
both to permit subtype polymorphism and to inherit
method implementations.
If there are no implementations to inherit, then an
interface is usually the preferable form.
Dynamic method invocation
Means that the JRE, when asked to invoke a
method on an object, looks at the actual
class of the object to find the method
implementation to execute.
Customer customer = new HumanCustomer();
String name = customer.getName();
In this case getName method from Customer
class is inherited and that gets executed.
Dynamic method invocation
(continued)
Oval oval = new FilledOval(1,2,10,20);
oval.draw(g);
In this case draw method from FilledOval and not Oval
gets executed.
More generally, when a subclass overrides an inherited
method then the overriding method implementation in
the subclass is always invoked when the method is
called on an object of the subclass.
Overloading Vs. Overriding
Two methods in the same class with the same name but different
parameter lists are said to be overloaded.
Overriding requires a superclass and subclass and refers to two methods
one in each class with the same signatures.
An example of overloading is the two versions of substring in String class:
public String substring(int beginIndex)
public String substring(int beginIndex, int endIndex)
You should only overload a method name if the methods with the same
name do essentially the same thing.
Overloading Vs. Overriding
(continued)
Overloading can be tricky if when methods with the same name have
parameters that involve subtypes.
All classes derive from Object and so inherit the following method:
public boolean equals(Object obj) // method 1
Suppose in a class called Automobile, the following method is added:
public boolean equals(Automobile auto) // method 2
equals method is overloaded in Automobile class.
Also equals method is overridden in Automobile class as follows:
public boolean equals(Object o) // method 3
Overloading Vs. Overriding
(continued)
Consider the following code:
Object o = new Object();
Automobile auto = new Automobile();
Object autoObject = new Automobile();
auto.equals(o);
auto.equals(auto);
auto.equals(autoObject);
o.equals(o);
o.equals(auto);
o.equals(autoObject);
autoObject.equals(o);
autoObject.equals(auto);
autoObject.equals(autoObject);
Overloading Vs. Overriding
(continued)
Dynamic method invocation causes the Java environment to look at the actual class
of the object being sent the message to determine which of several overridden
versions of a method to call.
For auto.equals(o), the compiler determines that the signature of method to be
called is equals(Object o).
At runtime, the actual class of auto (namely Automobile) is searched for a method
with the chosen signature. Therefore, method (3) is executed.
Similarly, method (3) will be executed in the calls auto.equals(autoObject),
autoObject.equals(o), autoObject.equals(auto), and autoObject.equals(autoObject).
Method (1) is executed in the calls o.equals(o), o.equals(auto), and o.equals
(autoObject), and method (2) is executed only in the call auto.equals(auto).
Access modifiers
public, private, protected and package level
For data it is best to never use public,
protected or package scope.
Design Rule 1
All data should be hidden in its class.
Design Rule 2
Users of a class must be dependent
on its public interface, but a class
should not be dependent on its
users.
Design rule 3
Minimize the number of messages
in the protocol of a class.
Assignment
Consider an Automobile class with the following
implementations of equals methods:
public boolean equals(Object o) {...}
//version A, inherited from Object
public boolean equals (Automobile o)
{...} //version B
and a class Sedan that is a subclass of Automobile
with the following methods:
public
{...}
public
{...}
Assignment (continued)
boolean equals(Automobile o)
//version C
boolean equals(Sedan o)
//version D
and a class Minivan that is a subclass of Automobile
with the following methods:
public
{...}
public
{...}
Assignment (continued)
boolean equals(Automobile o)
//version E
boolean equals(Minivan o)
//version F
Now suppose you have the following six variables:
Object o = new Automobile();
Automobile auto = new Automobile();
Automobile sedanAuto = new Sedan
(Color.black);
Automobile minivanAuto = new Minivan
(Color.blue);
Assignment (continued)
Sedan sedan = new Sedan(Color.grey);
Minivan minivan = new Minivan
(Color.pink);
There are 36 ways each of these variables can be
paired off in a call to equals, where one of the
6 variables is being sent the equals message and
one of the 6 is the argument to equals. For each
such pair, indicate which of the equals methods
will be executed. For example, if there is a call
auto.equals(auto)
then version B of equals will be called. Figure
out which equals method will be executed for the
other 35 combinations.

Vous aimerez peut-être aussi