1 / 32

The Object-oriented Programming Paradigm

The Object-oriented Programming Paradigm. As implemented in C++. Features. Encapsulation of data and operations on that data. Inheritance. Genericity. Polymorphism. Encapsulation of Data and Operations. More robust architecture. Localizes effects of changes in a program.

bailey
Download Presentation

The Object-oriented Programming Paradigm

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The Object-oriented Programming Paradigm As implemented in C++ Features • Encapsulation of data and operations on that data • Inheritance • Genericity • Polymorphism

  2. Encapsulation of Data and Operations More robust architecture • Localizes effects of changes in a program • Easier to maintain – program composed of objects is more stable under change than a program composed of functions • “Off the shelf” components can be built and used

  3. Encapsulation of Data and Operations Programmer can define access to the attributes and methods of the class • private – accessible only to member functions of the class • protected – accessible to member functions of the class and to operations in any descendant class • public – accessible to operations from all classes in the program

  4. Encapsulation of Data and Operations The programmer of a class can loosen the restrictions on access to private or protected features by declaring friend functions and friend classes class Node { friend class LinkedList; private: itemtype key; Node * next; }

  5. Friends have greater access to the features of a class than any “children” of the conferring class. Friends can access private attributes and methods, children can’t. In the previous example, descendants of LinkedList do not share friendship priviledges in Link. friend classes and functions Friends have access to private and protected features of a class The status of friend can only be given by a class. It cannot be claimed or inherited.

  6. Reasons for conferring “friend” status Known symbiotic dependencies between classes. Examples: Link and LinkedList Link, LinkedList, and ListIterator Function whose source parameter is an object of the class but whose target is a different object of the same class Example shown on next slide

  7. deposit (amt) is a message whose recipient is the target object. In transfer(Targ, Src, amt ) both the target object and the source object need to access private data. There is no one recipient of a message. Reasons for conferring “friend” status (cont.) class Account { private: double balance, credit_limit; public: //other operations void deposit(double amt); friendvoid transfer (Account & targ, Account & source, double amt}; }

  8. Genericity Container objects such as listsstacks and queues Have the same behaviors regardless of what kind of data object is being contained. To support reuse, we need to be able to create container classes that are capable of holding objects of a variety of types. This capability is provided in C++ by templates.

  9. Notation for templates private: T * buffer; int first; int capacity; User supplies capacity of a stack implemented as an array Include implementation file Templates Example template <class T> class Stack { public: Stack(int cap); ~Stack( ); void push(T item); void pop( ); T top ( ); boolean empty ( ); } #include Stack.cpp

  10. Dynamically allocated array Implementation using Templates template <class T> Stack <T> :: Stack (int cap) { buffer = new T[cap]; first = 0; capacity = cap; } Qualifier Stack <T>:: specifies both class and template parameter buffer is an array of objects of type (class) T where both the type of the contents T and the capacity are specified by the client at the time of compilation.

  11. template <class T> return_type class_name <T> :: Implementation using templates (cont.) template <class T> void Stack<T>:::push (T item) { if (first ==capacity) //raise exception -- not shown in abbreviated .h file error (OVERFLOW); buffer[first] = item; first++; } template <class T> T Stack<T>:: top( ) { if (first ==0) //raise UNDERFLOW error error (UNDERFLOW); return buffer[first]; } function()

  12. Limitation of Templates in Providing Genericity If items in a container are ordered, they must be able to respond to relational operators such as < or == (Not all classes have objects that are comparable –because the relational operators have not been overloaded in those classes or the objects are inherently incomparable and overloading the relational operators makes little sense.)

  13. Polymorphism Polymorphism is provided in C++ by the following: Overloading of functions and operators • Same function may be found in two or more classes • Function with the same name appears in one class with different sets of arguments Overriding methods in a descendant class to augment or refine behavior defined in the parent class • May change the implementation, but should never change the fundamental meaning of the method as defined in the parent. Substitution of one variable (object) type (class) for another at runtime • Dynamic bonding can be achieved in certain circumstances

  14. Operator Overloading Restrictions on overloading operators You can overload any operator except: . :: ?: sizeof You cannot define new operators by “overloading” symbols that are not already operators. At least one operand of an overloaded operator must be an instance of a class. You cannot change the precedence of a C++ operator, or the number of its operands.

  15. List size = 2 first last Operator Overloading Reasons for operator overloading: Overloading the = operator allows for “deep copy” of objects with dynamically allocated memory Example – Linked List

  16. Operator Overloading List List size = 2 size = 2 first first last last Shallow copy using the default = operator B = A; B.size = A.size; B.first = A.first; B.last = A.last; A B

  17. Format for declaring an overloaded operator function will be examined in the next couple of examples Operator Overloading Deep copy: List & List::operator = (const List & rhs) { //if the target is not empty, make it empty while (first != NULL) { link * temp = first; first = first -> next; delete temp; } link * ptr = rhs.first; while (ptr) { insert ( ptr -> key); //assumes insert at back of list ptr = ptr -> next; } return *this; } Deep copy produces an independent chain of links attached to the target List

  18. target of message is lhs target is not a member of class Complex Operator Overloading Consider the following example – class Complex (abridged) class Complex { private: double: re, im; public: Complex ( ); //default constructor Complex (double x, double y); //other member functions Complex & operator += (const Complex & rhs); friend Complex operator + (const Complex & scr1, const Complex & scr2); friend ostream & operator << (ostream & out, Complex & rhs); }

  19. Returns the object that this points to – the target Construct 2 complex number objects z2 is the target for the += operation Operator Overloading (cont.) Complex & Complex:: operator += (const Complex & rhs) { re += rhs.re; im += rhs.im; return * this; } This is a member function of class Complex • The left-hand side of the operator is the target object that receives the message Example: Complex z1(2, 3); Complex z2 (21, -24) ; z2 += z1;

  20. Target may be different from two sources or same as one of them Operator Overloading (cont.) Complex operator + (const Complex & src1, const Complex & src2) { Complex z; z,re = src1.re + src2.re; z,im = src1.im + src2.im; return z; } Sources scr1 and scr2 are passed by reference, but the const declarations prevents the programmer from changing their state. • This operator is not a member function of class Complex -- just a friend • no qualifier is used in its header. Return type is an object, not a reference -- each of the following assignments are permitted Complex z1, z2(1, 2), z3(-2, 4); z1 = z2 + z3; z2 = z2 + z3; cout << z2 + z3;

  21. Operator Overloading (cont.) ostream & operator << (ostream & out, const Complex & rhs) { out << ‘(‘ << rhs.re << “, “ << rhs.im << ‘)’; return out; } Returns a reference to the ostream object to provide for the sequencing of stream insertion operators in a single statement Complex z1(1.2, -2.1), z2(24, 44); cout << z1 << “+ “ << z2 “ = “ << z1 + z2 << endl;

  22. Substitution of types at Runtime The substitute must be a subclass of the declared type The original class (type) and the substitute must be referenced by a pointer Methods overridden in the subclass must be declared virtual in the parent.

  23. Dog Animal string name, says; int x_pos, y_pos; string name, says; int x_pos, y_pos; Dog ( ); //default Dog(constchar aname[]); //inherited methods void speak( ); //override Animal( ); //default Animal(constchar aname[]; //other non virtual methods virtualvoid speak( ); Substitution void chase_cats(Cat & acat); Parent class Descendant class Dogs bark “ruff, ruff” Animals are mute

  24. Default constructor – no name given Substitution Consider an array of (pointers to) Animals Animal * theBarn[4]; Now create some animals and put them in theBarn. Animal MickeyMouse(“Mickey”); Cat Sly (“Sylvester”); Dog Fred; Dog Spot (“Spot”); theBarn[0] = &MickeyMouse; theBarn[1] = &Sly; theBarn[2] = &Fred; theBarn[3] = &Spot;

  25. Substitutions Now tell each animal to speak for (int i = 0; i < 4; i++) theBarn[i] -> speak( ); The dogs will bark, the cat meow, and the mouse say that he is mute. But the dogs cannot chase cats!

  26. theBarn Dog Animal Cat Cat Felix Donald Noname Spot meow meow mute ruff Only methods and attributes in animal are seen Substitution The Farm Farm objects have a data member called theBarn that is an array of animal pointers

  27. Substitution An example that illustrates polymorphism Dog.h Cat.h Farm.h Animal.h farmyard.exe Strings.h farmyard.cpp Copy these files and see what happens when you do the following: • Remove virtual from in front of speak( ) in animal • Try having a dog chase one of the cats

  28. Shape Circle Rectangle Inheritance and Abstract Classes Example Shape is abstract It has no instances

  29. methods have no implementation Abstract Classes class Shape { protected: //data members needed if used for substitution int X, Y; double R1, R2; public: Shape (int x, y, double u, v); virtual double area ( ) = 0; virtual double perimeter ( ) = 0; } If at least one method is undefined, the class is abstract The abstract class Shape provides the specification for methods in the subclass, but no actual implementation. Two dimensional shapes have an area and a perimeter, but only specific shapes have formulae for computing them.

  30. Implementations of area and perimeter are specific to the subclass Inheriting from Abstract Classes class Circle : public Shape { public: Circle (int x, int y, double r) : X(x), Y(y), R1(r ), R2(0) {} double area ( ) {return M_PI * R1 *R1; } double perimeter ( ) {return 2 *M_PI * R1; } //other methods for Circle }

  31. Using Abstract Classes Abstract classes provide a Framework for adding application specific behavior User must supply the implementation details for all undefined methods. Abstract classes are useful as generalizations – where common behavior of separate but similar classes is abstracted out and placed in a common parent • Provides for design simplification • Provides for run-time polymorphism

  32. Target for reference param in retrieve Uses shape specific method Application using Template Class List <Shape *> L; Circle * p = new Circle(10, 12, 4.0); L.insert(p, 1); Circle * p2 = new Circle (15, 24, 3.6); L.insert(p2, 2); Rectangle * p3 = new Rectangle(21,36, 2.5, 4.1); L.insert(p3, 3); for (int i = 1; i <=L.length(); i++) { Shape * q; L.retrieve(i, q); q -> area ( ); }

More Related