1 cosc2767: object-oriented programming haibin zhu, ph. d. professor of computer science nipissing...
TRANSCRIPT
1
COSC2767: Object-Oriented Programming
Haibin Zhu, Ph. D.
Professor of Computer Science
Nipissing University
2
Lecture 2
Object-Oriented Design, Classes and Methods
3
Why Design ? Object-oriented thinking begins with
object-oriented design It is the easiest way to give the student
an appreciation of the problems of programming in the large (realistic modern software development).
Without understanding programming in the large, one cannot understand the importance of OOP
4
Activities in Software Development
Problem Analysis Program Design Coding Documenting Testing Maintenance
5
Remember Be clear about what you are trying to build. Successful software development is a long
term activity. The systems that we build tend to be at the
limit of the complexity that we and our tools can handle.
There are no cookbook methods that can replace intelligence, experience, and good taste in programming.
6
Remember Experimentation is essential for all non-
trivial software development. Design and programming are iterative
activities. The different phases of a software
project cannot be strictly separated. Programming and design cannot be
considered without also considering the management of these activities.
7
Strategy There is only one basic way to deal
with complexity: Divide and Conquer. Systems can be divided into
modules(Objects or Classes). The challenge is to ensure effective
communication between different parts of the program without destroying the divisions.
8
Objectives We are concerned with producing software
that satisfies the users’ requirements. The primary means to do so is to produce
software with a clean internal structure. The Tasks of OO Design:
To specify: The needed classes (or components) The interface
9
The Need for a Clean Internal Structure
To simplify: Testing Porting Maintenance Extension Re-organization Understanding
10
Characteristics of Successful Software
It has an extended life where it might be: worked on by succession of
programmers and designers ported to new hardware adapted to unanticipated uses
11
Some Issues of Design Identify Components Postponing Decisions Preparing for Changes Coupling and Cohesion Two views of a Software System Formalize the Interface Naming Documentation
12
Identify Components A component is simply an abstract entity that
can perform tasks or fulfill some responsibilities.
It may eventually be turned into a class, a function, a module, or something else.
A component must have a small, well-defined set of responsibilities.
A component should interact with other components to the minimal extent possible.
13
Postponing Decisions Many decisions can be ignored for the
moment Only need to note that somehow the user
can manipulate
14
Preparing for Change Your design team should also keep in mind that
change is inevitable. Users requirements change with experience, hardware changes, government regulations change.
Try to predict the most likely sources of change, and isolate the effect. Common changes include interfaces, file formats, communication protocols.
Isolate interfaces to hardware that is likely to change.
Reduce dependency of one software component on another.
Keep accurate record of the reasoning behind every major decision in the design documentation.
15
Design for Change The system must be designed to
remain as simple as possible under a sequence of changes.
We must aim for Flexibility Extensibility Portability
OOD can support the above.
16
Coupling and Cohesion
The separation of tasks into the domains of different components should be guided by the concepts of coupling and cohesion. Cohesion is the degree to which the tasks
assigned to a component seem to form a meaningful unit. Want to maximize cohesion.
Coupling is the degree to which the ability to fulfill a certain responsibility depends upon the actions of another component. Want to minimize coupling.
17
Parnas' Principles The developer of a software component must
provide the intended user with all the information needed to make effective use of the services provided by the component, and should provide no other information.
The implementer of a software component must be provided with all the information necessary to carry out the given responsibilities assigned to the component, and should be provided with no other information.
18
Public and Private View
Public view - those features (data or behavior) that other components can see and use
Private view - those features (data or behavior) that are used only within the component
19
Formalize the Interface The general structure of each component is
identified. Components with only one behavior may be made
into functions. Components with many behaviors are probably more
easily implemented as classes. Names are given to each of the responsibilities -
these will eventually be mapped on to procedure names.
Information is assigned to each component and accounted for.
Scenarios are replayed in order to ensure all data is available.
20
Naming The selection of names is an important
task. Names should be evocative in the context of
the problem. Names should be short. Names should be pronounceable (read them
out load). Names should be consistent within the
project. Avoid digits within a name.
21
Documentation The user manual describes the
application as seen by the user. Quality System Design Documentation
22
User Manual Does not depend upon the
implementation, so can be developed before the implementation.
Can naturally flow from the process of walking through scenarios.
Can be carried back to the clients to make sure the users and the implementers have the same ideas.
23
Quality You should always remember that the
primary measure of quality is the degree to which your customers (clients) are satisfied with your product.
Since often customers do not know exactly what it is they want, it is important to work with the client early in the design phase to make sure the system your are developing is the desired product. One very important way to do this is to create the user manual even before the software is written.
24
System Design Documentation
Record the decisions made during the process of system design.
Record the arguments for and against any major decision, and the factors influencing the final choice.
Use graphs (UML) for the major components. Maintain a log or diary of the process schedule. Important to produce this while the ideas are fresh,
not in hindsight when many details will have been forgotten.
Note the code only records the outcome of decisions, not factors that lead up to decisions being made.
25
Implement and Test Subsystems
Classic techniques, such as stepwise refinement, are used to implement each of the subsystems.
Subsystems are validated in isolation. Informal proofs of correctness for the subsystem
are developed. Identify necessary conditions for correct
functioning. Try to minimize conditions, and test input values whenever possible.
Software testing is used as a confidence building measure.
26
Integration and Testing
Components are slowly integrated into completed system.
Stubs can be used to perform testing all during integration.
Errors discovered during integration to cause reinvestigation of validation techniques performed at the subsystem level.
27
Maintenance and Evolution
Software does not remain fixed after the first working version is released. Errors or bugs can be discovered. Must be corrected. Requirements may change. Say as a result of government
regulations, or standardization among similar products. Hardware may change. Users expectations may change. Greater functionality,
more features. Often as a result of competition from similar products.
Better documentation may be required. A good design recognizes the inevitability of change,
and plans an accommodation for these activities from the very beginning.
28
Common Design Flaws Direct modification
Components that make direct modification of data values in other components are a direct violation of encapsulation.
Such coupling makes for inflexible designs. Too Much Responsibility (or services, methods)
Components with too much responsibility are difficult to understand and to use.
Responsibility should be broken into smaller meaningful packages and distributed.
No Responsibility Components with no responsibility serve no purpose. Often arise when designers equate physical existence with logical design
existence. Components with unused responsibility
Usually the result of designing software components without thinking about how they will be used.
Misleading Names Names should be short and unambiguously indicate what the
responsibilities of the component involve.
29
Classes and Methods Same Ideas, Different Terms Encapsulation and Instantiation Internal and External Views Behavior and State Class Definitions Methods Variations on Classes
30
Same Ideas, Different Terms
All OOP languages have the following concepts, although the terms they use may differ: classes, object type, factory object instances, objects message passing, method lookup, member
function invocation, method binding methods, member function, method function inheritance, subclassing
31
Encapsulation and Instantiation
Encapsulation - The purposeful hiding of information, thereby reducing the amount of details that need to be remembered/communicated among programmers.
A Service View - The ability to characterise an object by the service it provides, without knowing how it performs its task.
Instantiation - The ability to create multiple instances of an abstraction.
32
Common Behavior and State
A class can also be viewed as a combination of behavior and state. Behavior: The actions that an instance
can perform in response to a request. Implemented by methods.
State: The data that an object must maintain in order to successfully complete its behavior. Stored in instance variables (also known as data members, or data fields).
33
Design Steps of OOD
Find the Concepts/Classes and their most fundamental relationships.
Refine the Classes by specifying the sets of Operations on them classify these operations: constructors,
destructors, etc. consider minimalism, completeness, and
convenience
34
Design Steps (cont’d) Refine the classes by specifying their
dependencies on other classes: Inheritance dependencies Composition dependencies Use dependencies
Specify the interfaces for the classes: separate functions into public and protected
operations specify the exact type of the operations on
the classes.
35
Finding Classes Good design must capture and model
some aspects of reality. Look at the application rather than the
computer abstractions. Usually nouns correspond to classes
and verbs represent functions. Discussions with experts in the
application domain.
36
Behavior and State All classes can be characterized by two
aspects: The behavior of an object class is the set of
actions a component can perform. The complete set of behavior for an object is sometimes called the protocol.
The state of an object represents all the information (data values) held within an object.
Notice that it is common for behavior to change state. For example, the edit behavior of a recipe may change the preparation instructions, which is part of the state.
37
Example When ordering new videotapes from a supplier, the
store manager creates a purchase order, fills in the date, the supplier’s name , address, and enters a list of videotapes to be ordered. The purchase order is added to a permanent list of purchases. When one or more video tapes are received from a supplier, a clerk locates the original purchase order and makes a record of each tape that was received. A record of the videotape is then added to the store’s inventory. When all tapes listed on a particular purchase order have been received, the manager sends a payment to the supplier and the purchase order is given a completion date.
38
Specifying operations Consider how an object of the class is
constructed, copied, and destroyed. Define the minimal set of operations required
by the concept the class is representing. Consider which operations could be added
for notational convenience and include only a few really important ones.
Consider which operations are to be virtual. Consider what commonality of naming and
functionality can be achieved across all the classes of the component.
39
Operations on a Class Foundation:
Constructors and destructors Selectors( or Accessors):
Operations that do not modify the state of an object. Modifiers(or Setters):
Operations that modify the state of an object. Conversion Operators:
Operations that produce an object of another type based on the value (state) of the object to which they are applied.
Iterators: Operations that processes data members containing
collections of objects.
40
Specifying Dependencies
The key dependencies to consider in the context of design are inheritance and use relationships.
Overuse can lead to inefficient and incomprehensible designs.
41
Specifying Interfaces Private functions are not considered at
this stage. The interface should be implementation
independent (more than one implementation should be possible).
All operators in a class should support the same level of abstraction.
42
Reorganizing the Class Hierarchy
Typically, the initial organization of classes may not be adequate and therefore, we may have to reorganize to improve the design and/or implementation.
The two most common reorganizations of a class hierarchy are factoring of two classes into a new class splitting a class into two new ones.
43
Experimentation and Analysis
Prototyping is frequently used for experimenting.
Different aspects of a system may be prototyped independently, such as the graphical user interface.
Analysis of a design and/or implementation can be an important source of insight.
44
The Definition of Class
Class ::=<n, d, m, x>, where n is an Identification or a name of the
class; d is the space description (template) for
memory; m is the set of methods (or services,
operations) the objects of this class can make; and
x is a unified interface of all the objects of the class.
45
Class Definition in C++ class PlayingCard {
public:
enum Suits {Spade, Diamond, Club, Heart};
Suits suit () { return suitValue; }
int rank () { return rankValue; }
private:
Suits suitValue;
int rankValue;
};
46
Visibility Modifiers The terms public and private are used to
differentiate the internal and external aspects of a class. public features can be seen and manipulated by
anybody -- they are the external (interface or service) view.
private features can be manipulated only within a class. They are the internal (implementation) view.
Typically methods are public and data fields are private, but either can be placed in either category.
47
Methods A name that will be matched to a message to
determine when the method should be executed.
A signature, which is the combination of return type and argument types. Methods with the same name can be distinguished by different signatures.
A body, which is the code that will be executed when the method is invoked in response to a message.
48
Constructor class PlayingCard { // constructor, initialize new playing
card public PlayingCard (Suits is, int ir) { suit = is; rank = ir; faceUp = true; } ...
} A constructor is a method that is used to initialize a
newly constructed object. In C++, Java, C# and many other languages it has the same name as the class.
More about constructors in the next lecture.
49
Accessor (or getter) Methods
An accessor (or getter) is a method that simply returns an internal data value:
class PlayingCard { ... // operations on a playing card public int rank () { return rankValue; } public Suits suit () { return suitValue; } ... private int rankValue; }
50
Why Use an Accessor? You can make the data field read-only. It provides better documentation that
the data field is accessible It makes it easier to later change the
access behavior (count number of accesses, whatever).
51
Setters (or mutators) A setter (sometimes called a mutator method) is a
method that is used to change the state of an object:
class PlayingCard { // operations on a playing card public void setFaceUp (boolean up)
{ faceUp = up; } ... // private data values private boolean faceUp; }
52
Order of Methods List important topics first. Constructors are generally very
important, list them first. Put public features before private ones. Break long lists into groups List items in alphabetical order to make
it easier to search.
53
Separation of Definition and Implementation
In C++: class PlayingCard { public: ... Colors color () ; ... }; PlayingCard::Colors PlayingCard::color ( ) { // return the face color of a playing card if ((suit == Diamond) || (suit == Heart)) return Red; return Black; }
Notice need for fully-qualified names.
54
Considerations in Method Definitions
In C++ you have a choice to define a method in the class interface, or separately in an implementation file. How do you decide? Readability. Only put very small methods in
the class definition, so that it is easier to read. Semantics. Methods defined in class
interface may (at the discretion of the compiler) be expanded in-line. Another reason for only defining very small methods this way.
55
Variations on Classes Interfaces in Java (Methods without
Implementations) Nested classes in Java and C++ Class Data fields
56
Properties Properties are a way to define getters
and setters, but allow them to be used as if they were simple assignments and expressions:
writeln ('rank is ', aCard.rank); (* rank is property of card *)
aCard.rank = 5; (* changing the rank property *)
57
Inner or Nested Classes C++ or Java Whether the inner class can access features of the
outer class is different in different languages. class LinkedList { ... private class Link { // inner class public int value; public Link next; } }
58
Class Data Fields Idea is that all instances of a class can share
a common data field. Simple idea, but how to resolve the following paradox. All instances have the same behavior: Either they all initialize the common area, which
seems bad, or Nobody initializes the common area, which is also
bad.
Different languages use a variety of mechanisms to get around this.
59
Java Classclass PlayingCard { public int suit () { return suitValue; } public int rank () { return rankValue; } private int suitValue; private int rankValue; public static final int Spade = 1; public static final int Diamond = 2; public static final int Club = 3; public static final int Heart = 4;}Note: Java also applies visibility modifiers to each item
individually. Does not have enumerated data types, uses symbolic constants instead.
60
Template for Class Definition
class {
}
Import StatementsImport Statements
Class CommentClass Comment
Class NameClass Name
Data MembersData Members
Methods(incl. Constructor)
Methods(incl. Constructor)
61
Data Member Declaration
<modifiers> <data type> <name> ;
private String ownerName ;
ModifiersModifiers Data TypeData Type NameName
Note: There’s only one modifier in this example.
Note: There’s only one modifier in this example.
62
Method Declaration<modifier> <return type> <method name> ( <parameters> ){
<statements>
}
public void setOwnerName ( String name ) {
ownerName = name;
}StatementsStatements
ModifierModifier Return TypeReturn Type Method NameMethod Name ParameterParameter
63
Constructor A constructor is a special method that is executed when a new
instance of the class is created.
public <class name> ( <parameters> ){ <statements> }
public Bicycle ( ) {
ownerName = “Unassigned”;
}StatementsStatements
ModifierModifier Class NameClass Name ParameterParameter
64
The Definition of the Bicycle Class
class Bicycle { // Data Member private String ownerName;
//Constructor: Initialzes the data memberpublic Bicycle( ) {
ownerName = "Unknown";}
//Returns the name of this bicycle's owner public String getOwnerName( ) {
return ownerName; }
//Assigns the name of this bicycle's owner public void setOwnerName(String name) {
ownerName = name; } }
65
The Account Classclass Account { private String ownerName; private double balance; public Account( ) {
ownerName = "Unassigned"; balance = 0.0;
} public void add(double amt) { balance = balance + amt; } public void deduct(double amt) { balance = balance - amt; } public double getCurrentBalance( ) { return balance; }
public String getOwnerName( ) { return ownerName; }
public void setInitialBalance(double bal) { balance = bal; } public void setOwnerName(String name) {
ownerName = name; } }
66
Using Bicycle and Accountpublic class Application2 {
//This sample program uses both the Bicycle and Account classespublic static void main(String[] args) {Bicycle bike;Account acct;String myName = "Jon Java";bike = new Bicycle( ); bike.setOwnerName(myName);acct = new Account( );acct.setOwnerName(myName);acct.setInitialBalance(250.00);acct.add(25.00);acct.deduct(50);//Output some information System.out.println(bike.getOwnerName() + " owns a bicycle and");
System.out.println("has $ " + acct.getCurrentBalance() +" left in the bank");
}}//Application2.java
67
Java Visibility Modifiers
The modifiers public and private designate the accessibility of data members and methods.
If a class component (data member or method) is declared private, client classes cannot access it.
If a class component is declared public, client classes can access it.
Internal details of a class are declared private and hidden from the clients. This is information hiding.
68
Accessibility Example
class Service { public int memberOne; private int memberTwo;
public void doOne() {
…
} private void doTwo() {
…
}
}
…
Service obj = new Service();
obj.memberOne = 10;
obj.memberTwo = 20;
obj.doOne();
obj.doTwo();
…
Client Server
69
Data Members Should Be private
Data members are the implementation details of the class, so they should be invisible to the clients. Declare them private .
Exception: Constants can (should) be declared public if they are meant to be used directly by the outside methods.
70
Guideline for Visibility Modifiers
Guidelines in determining the visibility of data members and methods: Declare the class and instance variables private. Declare the class and instance methods private if
they are used only by the other methods in the same class.
Declare the class constants public if you want to make their values directly readable by the client programs. If the class constants are used for internal purposes only, then declare them private.
71
Static and Final Notice how symbolic constants are defined in
Java: static means that all instances share the same
value. One per class. Similar meaning in many languages.
final is Java specific, and means it will not be reassigned. (C++ has const keyword that is similar).
public static final int Spade = 1; public static final int Diamond = 2; public static final int Club = 3; public static final int Heart = 4;
72
Java Constantsclass Dice { private static final int MAX_NUMBER = 6; private static final int MIN_NUMBER = 1; private static final int NO_NUMBER = 0; private int number; public Dice( ) { number = NO_NUMBER; } //Rolls the dice public void roll( ) { number = (int) (Math.floor(Math.random() * (MAX_NUMBER - MIN_NUMBER + 1)) + MIN_NUMBER); } /Returns the number on this dice public int getNumber( ) { return number; } }
73
Summary Object-oriented Design
Programming in the large Design Steps Design Issues
Class and Methods Definition Visibilities Accessor and setters
Java Classes and Methods
74
The End
Interesting materials at
http://stwww.weizmann.ac.il/g-cs/benari/home/software.html#java