next up previous
Next: About this document Up: My Home Page

Object-Oriented Programming
Lecture 13

Steven S. Skiena

Why Objects are Good Things

Modules provide a logical grouping of procedures on a related topic.

Objects provide a logical grouping of data and associated operations.

The emphasis of modules is on procedures; the emphasis of objects is on data. Modules are verbs followed by nouns: Push(S,x), while objects are nouns followed by verbs: S.Push(x).

This provides only an alternate notation for dealing with things, but different notations can sometimes make it easier to understand things - the history of Calculus is an example.

Objects do a great job of encapsulating the data items within, because the only access to them is through the methods, or associated procedures.

Stack Object

MODULE StackObj EXPORTS Main;             (*24.01.95. LB*)
(* Stack implemented as object type. *)

  IMPORT SIO;

  TYPE
    ET    = INTEGER;                      (*Type of elements*)
    Stack = OBJECT
              top: Node := NIL;           (*points to stack*)
            METHODS
              push(elem:ET):= Push;       (*Push implements push*)
              pop() :ET:= Pop;            (*Pop  implements pop*)
              empty(): BOOLEAN:= Empty;   (*Empty implements empty*)
            END; (*Stack*)
    Node  = REF RECORD 
              info: ET;                   (*Stands for any information*)
              next: Node                  (*Points to the next node in the stack
*)
            END; (*Node*)

  PROCEDURE Push(stack: Stack; elem:ET) =  
  (*stack: receiver object (self)*)
  VAR 
    new: Node := NEW(Node, info:= elem);  (*Element instantiate*)
  BEGIN
    new.next:= stack.top;
    stack.top:= new;                      (*new element added to top*)
  END Push;

  PROCEDURE Pop(stack: Stack): ET =
  (*stack: receiver object (self)*)
  VAR first: ET;
  BEGIN
    first:= stack.top.info;               (*Info copied from first element*)
    stack.top:= stack.top.next;           (*first element removed*)
    RETURN first
  END Pop;

  PROCEDURE Empty(stack: Stack): BOOLEAN =
  (*stack: receiver object (self)*)
  BEGIN
    RETURN stack.top = NIL
  END Empty;

VAR
  stack1, stack2: Stack := NEW(Stack);    (*2 stack objects created*)
  i1, i2: INTEGER;
BEGIN
  stack1.push(2);                         (*2 pushed onto stack1*)
  stack2.push(6);                         (*6 pushed onto stack2*)
  i1:= stack1.pop();                      (*pop element from stack1*)
  i2:= stack2.pop();                      (*pop element from stack2*)
  SIO.PutInt(i1); 
  SIO.PutInt(i2);
  SIO.Nl();
END StackObj.

Object-Oriented Programming

Object-oriented programming is a popular, recent way of thinking about program organization.

OOP is typically characterized by three major ideas:

Inheritance

When we define an object type (class), we can specify that it be derived from (subtype to) another class. For example, we can specialize the Stack object into a GarbageCan:

  TYPE
    GarbageCan = Stack OBJECT
            OVERRIDES
              pop():= Yech;       (* Remove something from can?? *)
              dump():= RemoveAll; (* Discard everything from can *)
            END; (*GarbageCan*)

The GarbageCan type is a form of stack (you can still push in it the same way), but we have modified the pop and dump methods.

This subtype-supertype relation defines a hierarchy (rooted tree) of classes. The appropriate method for a given object is determined at run time (dynamic binding) according to the first class at or above the current class to define the method.

OOP and the Calculator Program

How might object-oriented programming ideas have helped in writing the calculator program?

Many of you noticed that the linked stack type was similar to the long integer type, and wanted to reuse the code from one in another.

The following type hierarchy shows one way we could have exploited this, by creating special stack methods push and pop, and overwriting the add and subtract methods for general long-integers.

Philosophical issue: should Long-Integer be a subtype of Positive-Long-Integer or visa versa?

Why didn't I urge you to do it this way? In my opinion, the complexity of mastering and using the OOP features of Modula-3 would very much overwhelm the code savings from such a small program. Object-oriented features differ significantly from language to language, but the basic principles outlined here are fairly common.

However, you should see why inheritance can be a big win in organizing larger programs.




next up previous
Next: About this document Up: My Home Page

Steve Skiena
Wed Oct 8 08:34:52 EDT 1997