Object oriented programming and object oriented design
This presentation is the property of its rightful owner.
Sponsored Links
1 / 50

Object Oriented Programming and Object Oriented Design PowerPoint PPT Presentation


  • 87 Views
  • Uploaded on
  • Presentation posted in: General

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.

Download Presentation

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Object Oriented ProgrammingandObject Oriented Design

Programming Languages

Robert Dewar


Object Oriented Programming

  • OOP provides three fundamental functionalities:

    • Type extension

    • Inheritance

    • Dynamic Polymorphism


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.


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


  • 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


    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


    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


  • 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


    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.


    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


    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


    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.


    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


    Using Variant Records (cont)

    • Code that is not common has a case statement:

      • case Object.DiscrimValue iswhen val1 => …when val2 => ……end case;


    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.


    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.


    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


    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).


    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.


    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


    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


    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 MybaseIncluding for example Print and New_Base

  • But you can redefine (override) any inherited operations.


  • 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


    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


  • 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


    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.


    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)


    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


  • 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;


    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!


    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’(….);


    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


    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)


    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.


    Object-Oriented programming in C++

    • Classes as units of encapsulation

    • Information Hiding

    • Inheritance

    • polymorphism and dynamic dispatching

    • Storage management

    • multiple inheritance


    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);

      }


    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.


    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.


    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.


    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);


    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 ();


    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


    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?


    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


    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


    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


    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


    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


    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


    OOP in Java

    • To be supplied!


  • Login