1 / 50

Object Oriented Programming and Object Oriented Design

Object Oriented Programming and Object Oriented Design. Programming Languages Robert Dewar. Object Oriented Programming. OOP provides three fundamental functionalities: Type extension Inheritance Dynamic Polymorphism. Type Extension.

krock
Télécharger la présentation

Object Oriented Programming and Object Oriented Design

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. Object Oriented ProgrammingandObject Oriented Design Programming Languages Robert Dewar

  2. Object Oriented Programming • OOP provides three fundamental functionalities: • Type extension • Inheritance • Dynamic Polymorphism

  3. Type Extension • The problem, given an existing type, add additional capabilities retaining the original • Make the extended type look as much like the original as possible • Typical implementation, add fields or components to an existing record type.

  4. Faking Type Extension • Could make a new record • With new components • And retaining the old type as one component • type Ext is record Parent : Old; Newf : Integer;end record; • But that would not look much like original • If Newobj is of type Ext • Cannot say Ext.Value • Must say Ext.Parent.Value

  5. Inheritance • Goes along with type extension • When a type is extended • New type has all the operations of the old type, with the same meaning. • Of course they do not know about the new fields, and do not reference them • But most code that worked for the base type works for the extended type without change

  6. More on Inheritance • Cannot always use operations of base type • May need to mess with new fields • In particular constructors must do so • May have different semantics from new field • Should be able to “override” inherited operations when type is extended • Must override constructors • Can also add new operations for new extended type

  7. Faking Inheritance • If you fake type extension • You could add definitions for every operation. Most would look like • procedure Operate (X : Ext) isbegin Operate (X.Parent);end Operate; • That’s rather annoying • And generates a lot of junk

  8. Ad Hoc Polymorphism • More familiar term is overloading • Applies in this situation as follows • If we have several types derived from a common parent with an operation Op • Suppose Op is overridden for some types • If a variable has a particular type, then the compiler can figure out what Op you mean from the type of the variable

  9. Dynamic Polymorphism • Also called dynamic dispatching • Addresses problems where you have data structures that are heterogenous and can contain different kinds of data. • The data items are similar (e.g. obtained by type extension from a common base). • And therefore have a similar set of operations.

  10. More on Dynamic Dispatching • Now suppose we apply Op to a variable which at run time can have more than one possible “type”. • What we want is that at runtime, the proper Op is picked, based on the current type of the object in the variable • This is called dynamic dispatching

  11. Faking Dynamic Dispatching • We could have record fields that contained pointers to the function to be called. • Actually that’s how dynamic dispatching is usually implemented: • Record contains a pointer to a table • Table has (at fixed offsets for any given operation), address of function to be called. • Different types have different tables

  12. An Approach to Compare • The issue is that we want a variable that can have several different forms at runtime. • And we have some code that depends on which particular form it has. • And some code that is the same for all types.

  13. Using Variant Records • Instead of N types extended from a given base type, use a variant record with N different possibilities. • Fields of parent correspond to common fields in the variant record • Code that does not depend on type just accesses these common fields

  14. Using Variant Records (cont) • Code that is not common has a case statement: • case Object.DiscrimValue is when val1 => …when val2 => … …end case;

  15. Comparing the Approaches • Consider that you have N operations and T types, then potentially you have N*T different functions, but in practice many of the functions are the same for many types. • Case statement means you have one unit per operation, using case to select • Dynamic dispatching means you have one unit per type, with overridden operations.

  16. Comparing the Approaches (cont.) • If you often add operations, the case statement approach is easier, add one new unit for new operation providing base code with case statements as required • If you often add types, the dynamic dispatching approach is easier, add one new unit for new type overriding any operations where base code is wrong.

  17. OOP and Reuse • By making your types extendible • You increase reuse capabilities • Instead of editing your code in places where it does not apply • A client extends your types, and overrides your code where it does not apply

  18. Object Oriented Design • Has nothing to do with OOP per se • Relates not to language features but to the design approach • It may be that OOP features are useful for object oriented design (OOD).

  19. OOD – The Basic Idea • The problem is modeled as a set of objects, preferably related to the structure of the problem, that represent real objects in the world. These objects have state. • Computation proceeds by passing messages (requests, signals, commands, reports) between objects.

  20. How does OOD relate to OOP • In the real world, objects are built by specializing more general notions • A Toyota Previa is an instance of Car with extra info, which is an instance of Vehicle with extra information, etc. • Type extension • All cars work mostly the same • Inheritance • But for some features, cars differ • Dynamic dispatching

  21. OOP Features in Ada 83 • Ada 83 provides features for • Inheritance • But does not provide • Type extension • Dynamic dispatching • Inheritance is provided via derived types • Other OOP features deliberately omitted • Designers were very familiar with Simula-67 • But felt that genericity was a better approach

  22. Derived Types • Declare a type and some operations on it • type Base is ….procedure Print (Arg : Base);function New_Base return Base; • Now derive a new type • type Mybase is new Base; • All operations are available on Mybase Including for example Print and New_Base • But you can redefine (override) any inherited operations.

  23. OOP In Ada 95 • Genericity is not enough • Market demands OOP features • So in Ada 95 features are added for • Type Extension • Dynamic Dispatching • But multiple inheritance is deliberately omitted

  24. Tagged Types in Ada 95 • A tagged type has a dynamic tag showing what type the object is. Otherwise it looks like a record • type Base is tagged record X : Integer; Y : Float;end record; • Can also have tagged private types • type Base is tagged private; • Completion must be tagged record

  25. Type Extension • A tagged type can be extended • Using an extension of derived type idea • type Mybase is new Base with record B : Boolean; D : Duration;end record; • All operations are inherited • Except for constructors (functions returning values of type Base) • Constructors must be overridden • Since they need to know about the new fields

  26. How type Extension Works • New fields are added at the end of the record, with original fields at the start. • A subprogram that is only referencing the original fields can do this on the base type or any type derived from it. • Because the original fields are always at the same offset from the start of the record. • This model does not extend well to the case of multiple inheritance.

  27. Type extension and overloading • Suppose a client has • B : Base; • M : Mybase; • And there is an operation D that was not overridden: • D (B); D (M); • Correct proc called, but in fact does same thing • And there was an overridden operation O • O (B); O (M); • Correct proc called (static overloading)

  28. Converting Among Types • Suppose we have an operation Q that is defined for Base and was not inherited • Because it was not defined in original package • And now we have a Mybase: • M : Mybase; • And we want to call Q on M: • Q (M); -- no good, wrong type • Q (Base (M)) -- that’s ok, a view conversion

  29. Using conversion when Overriding • Suppose we have a procedure Dump defined on Base • For Mybase we want to dump the new fields and then call the original dump • procedure Dump (X : Mybase) isbegin … dump new fields Dump (Base (X)); -- calls original Dumpend Dump;

  30. Converting the Other Way: NOT • Suppose we have an operation M that is defined for Mybase, and we have an object of type Base: • B : Base; • And we want to apply M to B • You are out of luck, can’t do it • After all M might refer to extended fields!

  31. Class Variables • Suppose you want a data structure that holds a mixture of objects of type Base and Mybase. • The type Base’Class is a type that includes values of tagged type Base and all types derived from Base. • type Bptr is access Base’Class; • BC_Ptr : Bptr := new Base’(….);BC_Ptr := new Mybase’(….);

  32. Dynamic Dispatching • If a subprogram, say Draw is defined as a primitive operation of type Base (defined along with type Base) • Then not only is it inherited by any type derived from Base • But it is also defined on Base’Class

  33. Special Treatment of Base’Class • The subprogram • procedure Draw (Arg : Base’Class); • That is derived automatically • Has special semantics • It is called with an object of the appropriate type (e.g. BC_Ptr.all) • The result is to call the version of Draw that is appropriate to the actual run-time type of the argument (looks at the tag)

  34. How Dynamic Dispatching Works • Tag is actually a pointer to a table • One table for each type • In our example, two tables • One table for Base • Different table for Mybase • Table contains pointers to subprograms • Put new ones at end • First entries in Mybase table are a copy of the entries in the Base table unless overridden.

  35. Object-Oriented programming in C++ • Classes as units of encapsulation • Information Hiding • Inheritance • polymorphism and dynamic dispatching • Storage management • multiple inheritance

  36. Classes • Encapsulation of type and related operations class point { double x,y; // private data members public: point (int x0, int y0); // public methods point () { x = 0; y = 0;}; // a constructor void move (int dx, int dy); void rotate (double alpha); int distance (point p); }

  37. A class is a type : objects are instances point p1 (10, 20); // call constructor with given arguments point p2; // call default constructor Methods are functions with an implicit argument p1.move (1, -1); // special syntax to indicate object // in other languages might write move (p1, 1, -1) // special syntax inspired by message-passing metaphor: // objects are autonomous entities that exchange messages.

  38. Implementing methods No equivalent of a body: each method can be defined separately void point::rotate (double alpha) { x = x * cos (alpha) - y * sin (alpha); y = y * cos (alpha) + x * cos (alpha); }; // x and y are the data members of the object on which the // method is being called. // if method is defined in class declaration, it is inlined.

  39. Constructors • One of the best innovations of C++ • special method (s) invoked automatically when an object of the class is declared point (int x1, int x2); point (); point (double alpha; double r); point p1 (10,10), p2; p3 (pi / 4, 2.5); • Name of method is name of class • Declaration has no return type.

  40. The target of an operation • The implicit parameter in a method call can be retrieved through this: class Collection { Collection& insert (thing x) { // return reference … modify data structure return *this; // to modified object }; }; my_collection.insert (x1).insert (x2);

  41. Static members • Need to have computable attributes for class itself, independent of specific object; e.g. number of objects created. • Static qualifier indicates that entity is unique for the class staticint num_objects = 0; point () { num_objects++;}; // ditto for other constructors • Can access static data using class name or object name: if (point.num_objects != p1.num_objects) error ();

  42. Classes and private types • If all data members are private, class is identical to a private type: visible methods, including assignment. • A struct is a class with all public members • How much to reveal is up to programmer • define functions to retrieve (not modify) private data int xcoord () { return x;}; int ycoord () { return y;}; p2.x = 15; // error, data member x is private

  43. Destructors • If constructor allocates dynamic storage, need to reclaim it class stack { int* contents; int sz; public: stack (int size) { contents = newint [ sz = size];}; void push (); int pop (); int size () { return sz;}; } stack my_stack (100); // allocate storage dynamically // when is my_stack.contents released?

  44. If constructor uses resources, class needs a destructor • User cannot deallocate data because data member is private: system must do it ~stack ( ) {delete[ ] contents;}; • inventive syntax: negation of constructor • Called automatically when object goes out of scope • Almost never called explicitly

  45. Copy and assignment point p3 (10,20); point p5 = p3; // componentwise copy • This can lead to unwanted sharing: stack stack1 (200); stack stack2 = stack1; // stack1.contents shared stack2.push (15); // stack1 is modified • Need to redefine assignment and copy

  46. Copy constructor stack (const stack& s) { // reference to existing object contents = new int [ sz = s.size()]; for (int I = 0; I <sz; I++) contents [I] = s.contents [I]; } stack s1 (100); … stack s2 = s1; // invokes copy constructor

  47. Redefining assignment • Assignment can also be redefined to avoid unwanted sharing • Operator returns a reference, so it can be used efficiently in chained assignments: one = two = three; stack & operator= (const stack& s) { if (this != &s) { // beware of self-assignment delete [] contents; // discard old value contents = newint [sz = s.size ()]; for (int I = 0; I <sz; I++) contents [I] = s.contents [I]; } return *this; } stack s1 (100), s2 (200); … s1 = s2; // transfer contents

  48. Differences Between Ada and C++ • C++ model much more specialized to the notion of OOD • Distinguished first parameter is object involved • No easy way of defining binary operators • Prefix notation nice for objects but awkward for values • C++ allows multiple inheritance

  49. Doing Multiple Inheritance in Ada • We can have one field that we add be an instance of some other base type. • We can use generics to parametrize this additional type • Worked out examples in Ada 95 Rationale • Which you can find at www.adapower.com

  50. OOP in Java • To be supplied!

More Related