Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 14 Object-Oriented Software Development

Similar presentations


Presentation on theme: "Chapter 14 Object-Oriented Software Development"— Presentation transcript:

1 Chapter 14 Object-Oriented Software Development
Dale/Weems/Headington

2 Chapter 14 Topics Structured Programming vs. Object-Oriented Programming Operator Overloading Using Inheritance to Create a New C++ class Type Using Composition (Containment) to Create a New C++ class Type Static vs. Dynamic Binding of Operations to Objects Virtual Member Functions

3 Two Programming Paradigms
Structural (Procedural) Object-Oriented PROGRAM PROGRAM OBJECT Operations Data FUNCTION FUNCTION OBJECT Operations Data OBJECT Operations Data FUNCTION

4 Object-Oriented Programming Language Features
1. Data abstraction 2. Encapsulation 3. Inheritance of properties 4. Dynamic binding of operations to objects

5 OOP Terms C++ Equivalents
Object Class object or class instance Instance variable Private data member Method Public member function Message passing Function call ( to a public member function )

6 What is an object? OBJECT Operations Data set of methods
(public member functions) internal state (values of private data members) Operations Data

7 Operator Overloading

8 Complex Number Domain: Operations: x, y, and z complex
X = a + bi  Real and Imaginary parts Operations: x, y, and z complex - x negate z = x+y z = x – y z = c*x where c is a scalar Output a complex number; Read a complex number;

9 Class Complex Number: Specification
private: double Real, Im; public: complex(); complex (double R, double I); complex negate (void); // Negation complex add (const complex & Y); // Addition complex sub (const complex & Y); // Subtraction bool IsEqual (const complex & Y) const ; // equality complex ScalarMult (const double& c); void output ( ); // outputs Real and Im to cout void input ( ); // reads from cin into Real and Im };

10 Operator Overloading Only C++ built-in operators can be overloaded
Overloaded operator obeys the precedence, associativity, and number of operands dictated by the built-in operator When an operator is overloaded as a member function, the object associated with the operator is the left-most operand example: X + Y <=> X.operator + (Y) => left-most operand must be an object of the class of which the operator is a member. If that is not the case, instead of using a member operator use a friend operator.

11 Complex ADT Multiplication of a Complex by a Scalar
c * X = (c * X.Real, c * X.Im) Note: In C++, c * X would be translated to c.operator * (X) The left-most operand of an overloaded operator must be an object of the class being defined. => can not overload the * for complex scalar multiplication Solution: use a friend function

12 Overloading Operators
Stream I/O operators complex X, Y; cin >> X; // Left-most operand is Not an object cin >> X >> Y; // of type complex cout << “Here is a complex number” << X; cout << X << Y << endl;

13 Class Complex: Specification
private: double Real, Im; public: complex(); complex (double R, double I); complex operator - (void); // Negation complex operator +(const complex & Y); // Addition complex operator - (const complex & Y); // Subtraction bool operator == (const complex & Y) const ; // equality friend complex operator * (const double& c, const complex& X); friend istream& operator >> (istream& istr, complex& X); friend ostream& operator << (ostream& ostr, const complex& X); };

14 Class Complex: Implementation
complex:: complex(double R, double I) { // The Constructor Real = R; Im = I; } complex complex:: operator - (void) { // returns the value complex(-Real, -Im) return complex( -Real, - Im ); complex complex::operator + (const complex& Y) { // returns the value complex(Real + Y.Real, Im + Y.Im) complex temp; temp.Real = Real+Y.Real; temp.Im = Im + Y.Im; return temp

15 complex complex::operator - (const complex& Y)
{ complex temp; temp.Real = Real - Y.Real; temp.Im = Im - Y.Im; return temp } Client code …. complex A(2,3) , B(5, 7), C; B = -A; equivalent to B = operator-(A); C = A + B; equivalent to C = A.operator+(B); C = A - B; equivalent to C = A.operator - (B);

16 Friend Functions/Operators
complex operator * (const double& c, const complex& X) { complex temp; temp.Real = c* X.Real; temp.Im = c * X.Im; return temp } A friend function is a function defined outside of the class scope. Note: there is no scope resolution It is a friend function because in the class specification the keyword “friend” is used in the prototype A friend function of a class has access to the private members of the class Inside the function definition, the dot operator is required to access the class data members. Note that for a binary operation, two arguments are required

17 Overloaded Stream Input Operator >>
istream& operator >> (istream& istr, complex& X) { // paramter istr represents an input stream such cin // The two parameters are passed by reference because they are // modified by the function // The function returns a reference to an istream object so that input // operations can be chained istr >> X.Real >> X.Im ; return istr ; } Example: complex A, B ; cin >> A >> B;

18 Overloaded Stream Output Operator <<
ostream& operator << (ostream& ostr, const complex& X) { // The second parameter is passed by reference; but it is read-only ostr << X.Real << X.Im ; return ostr ; } Example: complex A, B; …… cout << A << B;

19 Inheritance Hierarchy Among Vehicles
wheeled vehicle boat bicycle car four-door two-door Every car is a wheeled vehicle.

20 Inheritance is a mechanism by which one class acquires (inherits) the properties (both data and operations) of another class the class being inherited from is the Base Class (Superclass) the class that inherits is the Derived Class (Subclass) the derived class is then specialized by adding properties specific to it

21 class Time Specification
// SPECIFICATION FILE ( time.h ) class Time { public : void Set ( int hours , int minutes , int seconds ) ; void Increment ( ) ; void Write ( ) const ; Time ( int initHrs, int initMins, int initSecs ) ; // constructor Time ( ) ; // default constructor private : int hrs ; int mins ; int secs ; } ; 21

22 Class Interface Diagram
Time class Set Private data: hrs mins secs Increment Write Time Time

23 Using Inheritance to Add Features
// SPECIFICATION FILE ( exttime.h) #include “time.h” enum ZoneType {EST, CST, MST, PST, EDT, CDT, MDT, PDT } ; class ExtTime : public Time // Time is the base class { public : void Set ( int hours, int minutes, int seconds , ZoneType timeZone ) ; void Write ( ) const ; ExtTime ( int initHrs , int initMins , int initSecs , ZoneType initZone ) ; // constructor ExtTime ( ) ; // default constructor private : ZoneType zone ; // added data member } ; 23

24 class ExtTime: public Time
says class Time is a public base class of the derived class ExtTime as a result, all public members of Time (except constructors) are also public members of ExtTime in this example, new constructors are provided, new data member zone is added, and member functions Set and Write are overridden

25 Class Interface Diagram
ExtTime class Set Set Private data: hrs mins secs Increment Increment Write Write ExtTime Time ExtTime Time Private data: zone

26 Client Code Using ExtTime
#include “exttime.h” . ExtTime thisTime ( 8, 35, 0, PST ) ; ExtTime thatTime ; // default constructor called thatTime.Write( ) ; // outputs 00:00:00 EST cout << endl ; thatTime.Set (16, 49, 23, CDT) ; thatTime.Write( ) ; // outputs 16:49:23 CDT cout << endl ; thisTime.Increment ( ) ; thisTime.Write ( ) ; // outputs 08:35:02 PST 26

27 Constructor Rules for Derived Classes
at run time, the base class constructor is implicitly called first, before the body of the derived class’s constructor executes if the base class constructor requires parameters, they must be passed by the derived class’s constructor

28 Implementation of ExtTime Default Constructor
ExtTime :: ExtTime ( ) // Default Constructor // Postcondition: // hrs == 0 && mins == 0 && secs == 0 // (via an implicit call to base class default constructor ) // && zone == EST { zone = EST ; }

29 Implementation of Another ExtTime Class Constructor
ExtTime :: ExtTime ( /* in */ int initHrs, /* in */ int initMins, /* in */ int initSecs, /* in */ ZoneType initZone ) : Time (initHrs, initMins, initSecs) // constructor initializer // Precondition: 0 <= initHrs <= && 0 <= initMins <= 59 // <= initSecs <= 59 && initZone is assigned // Postcondition: // zone == initZone && Time set by base class constructor { zone = initZone ; } 29

30 Implementation of ExtTime::Set function
void ExtTime :: Set ( /* in */ int hours, /* in */ int minutes, /* in */ int seconds, /* in */ ZoneType time Zone ) // Precondition: 0 <= hours <= && 0 <= minutes <= 59 // <= seconds <= 59 && timeZone is assigned // Postcondition: // zone == timeZone && Time set by base class function { Time :: Set (hours, minutes, seconds); zone = timeZone ; } 30

31 Implementation of ExtTime::Write Function
void ExtTime :: Write ( ) const // Postcondition: // Time has been output in form HH:MM:SS ZZZ // where ZZZ is the time zone abbreviation { static string zoneString[8] = “EST”, CST”, MST”, “PST”, “EDT”, “CDT”, “MDT”, “PDT” } ; Time :: Write ( ) ; cout << ‘ ‘ << zoneString [zone] ; } 31

32 Avoiding Multiple Inclusion of Header Files
often several program files use the same header file containing typedef statements, constants, or class type declarations--but, it is a compile-time error to define the same identifier twice this preprocessor directive syntax is used to avoid the compilation error that would otherwise occur from multiple uses of #include for the same header file #ifndef Preprocessor_Identifier #define Preprocessor_Identifier . #endif

33 Composition (or Containment)
is a mechanism by which the internal data (the state) of one class includes an object of another class

34 A TimeCard object has a Time object
#include “time.h” class TimeCard { public: void Punch ( /* in */ int hours, /* in */ int minutes, /* in */ int seconds ) ; void Print ( ) const ; TimeCard ( /* in */ long idNum, /* in */ int initHrs, /* in */ int initMins, /* in */ int initSecs ) ; TimeCard ( ) ; private: long id ; Time timeStamp ; } ;

35 TimeCard Class TimeCard has a Time object Punch Print TimeCard
Private data: id timeStamp Punch Print . Private data: hrs mins secs Set Increment Write . TimeCard TimeCard

36 Implementation of TimeCard Class Constructor
TimeCard :: TimeCard ( /* in */ long idNum, /* in */ int initHrs, /* in */ int initMins, /* in */ int initSecs ) : timeStamp (initHrs, initMins, initSecs) // constructor initializer // Precondition: 0 <= initHrs <= && 0 <= initMins <= 59 // <= initSecs <= 59 && initNum is assigned // Postcondition: // id == idNum && timeStamp set by its constructor { id = idNum ; } 36

37 Order in Which Constructors are Executed
Given a class X, if X is a derived class its base class constructor is executed first next, constructors for member objects (if any) are executed (using their own default constructors if none is specified) finally, the body of X’s constructor is executed

38 In C++ . . . When the type of a formal parameter is a
parent class, the argument used can be: the same type as the formal parameter, or, any descendant class type.

39 Static Binding is the compile-time determination of which function to call for a particular object based on the type of the formal parameter when pass-by-value is used, static binding occurs

40 Static Binding Is Based on Formal Parameter Type
void Print ( /* in */ Time someTime ) { cout << “Time is “ ; someTime.Write ( ) ; cout << endl ; } CLIENT CODE OUTPUT Time startTime ( 8, 30, 0 ) ; Time is 08:30:00 ExtTime endTime (10, 45, 0, CST) ; Time is 10:45:00 Print ( startTime ) ; Print ( endTime ) ;

41 Dynamic Binding is the run-time determination of which function to call for a particular object of a descendant class based on the type of the argument declaring a member function to be virtual instructs the compiler to generate code that guarantees dynamic binding

42 Virtual Member Function
// SPECIFICATION FILE ( time.h ) class TimeType { public : virtual void Write ( ) const ; // for dynamic binding private : int hrs ; int mins ; int secs ; } ;

43 Dynamic binding requires pass-by-reference
void Print ( /* in */ Time & someTime ) { cout << “Time is “ ; someTime.Write ( ) ; cout << endl ; } CLIENT CODE OUTPUT Time startTime ( 8, 30, 0 ) ; Time is 08:30:00 ExtTime endTime (10, 45, 0, CST) ; Time is 10:45:00 CST Print ( startTime ) ; Print ( endTime ) ;

44 Using virtual functions in C++
dynamic binding requires pass-by-reference when passing a class object to a function in the declaration for a virtual function, the word virtual appears only in the base class if a base class declares a virtual function, it must implement that function, even if the body is empty a derived class is not required to re-implement a virtual function. If it does not, the base class version is used


Download ppt "Chapter 14 Object-Oriented Software Development"

Similar presentations


Ads by Google