0% found this document useful (0 votes)
22 views

CH 12

Smalltalk was the first pure object-oriented programming language. It introduced key OOP concepts like classes, inheritance, polymorphism, and message passing. All computation is done by sending messages between objects. Smalltalk uses single inheritance and dynamic binding. Methods are defined by interacting with classes, and blocks provide control structures like conditionals and loops. Smalltalk demonstrated the power of the object-oriented paradigm but had limitations in efficiency and mathematical capabilities compared to imperative languages.

Uploaded by

roshan paswan
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views

CH 12

Smalltalk was the first pure object-oriented programming language. It introduced key OOP concepts like classes, inheritance, polymorphism, and message passing. All computation is done by sending messages between objects. Smalltalk uses single inheritance and dynamic binding. Methods are defined by interacting with classes, and blocks provide control structures like conditionals and loops. Smalltalk demonstrated the power of the object-oriented paradigm but had limitations in efficiency and mathematical capabilities compared to imperative languages.

Uploaded by

roshan paswan
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 28

Object-Oriented Programming

• Objects were first introduced in Simula 67


– although the intent in Simula was not to provide a new programming
paradigm, but instead to offer a construct to easily build models for
simulation purposes
• OOP was developed fully in Smalltalk
– the object can be thought of as an extension to ADTs except that the
structure can be extended for easy modification leading to a hierarchically
organization
• message-passing was implemented rather than function calls
• encapsulation was enforced through the class construct
• different types of objects call upon the same method if the objects were related
hierarchically, leading to polymorphism and generic methods
• OOPL was later included in many languages
– C++ (a descendent of C with many of Smalltalk’s class ideas)
– Common Lisp (added to CL was CLOS, the Common Lisp Object System)
– Ada 95 (Ada 83 + objects)
– Java and C# introduce a newer generation of OOPLs related to C++ but
cleaner and easier to understand
– Scripting languages started adding objects with JavaScript and has
continued with both Python and Ruby (Ruby is the only pure OOPL since
Smalltalk)
OOPL Definitions
• Pure OOP: all computation done by message passing
• Hybrid OOP: computation shared between message passing and
function calls
– most OOPLs are hybrids (C++, Ada 95, Delphi, Common Lisp, C#)
– Java would be pure if not for the 8 primitive types
• Inheritance: to solve the modification problem; controls what
definitions a subclass obtains from a parent class
– to control inheritance, the language might include modifiers such as private,
public and protected
• question: can a subclass override a parent’s definition?
• if so, can the parent item still be accessed or is it hidden?
– question: is multiple inheritance available? (C++ and CLOS have this)
• Polymorphism: variables that can reference any subclass of a given
class
– we need a mechanism to bind a message to the proper method, which is often
done at run time so is called dynamic type binding
Class/Subclass Relationships
• Aside from C++ and Common Lisp, classes in other
languages must have one (and only one) parent
– any defined class needs a parent, what is that parent’s parent?
• with this restriction, such languages will offer a starting class
– usually called Object
– what if a parent class is not specific enough to have an
implementation for its methods but all child classes should
have the given methods?
• in this case, we can make the methods in the parent class abstract (also
known as virtual)
• this forms what is known as an interface in Java
– an interface means that the pre-specified abstract methods must be
implemented in any class that implements (inherits from) the interface
• classes with abstract entities cannot themselves be instantiated, but can
be extended into subclasses
Design Issues
• Exclusitivity of Objects
– are all types classes, or are there other types?
• dictates whether all communication is via message passing or if other
forms are provided and whether the language is pure OOP or hybrid
• Subclass relationships
– is a subclass a descendant of the class (is-a relationship)
– or some different relationship such as a subrange or subset
• Inheritance and information hiding
– how are these provided? is information hiding enforced?
• Type checking and polymorphism
– is type checking done and if so, when? Note: we will explore
– can variables be polymorphic? sample programs from
• Single vs. multiple inheritance many of the languages
– which is allowed? discussed here on-line
so this set of notes largely
• Allocation and Deallocation of Objects omits specific examples
– when and how is this performed?
Smalltalk
• Programs consist only of objects and messages
– variables are local (private) or global (shared)
• all vars are pointed to by ptrs
– inheritance
• single inheritance only, subclasses inherit everything from the parent
– class methods/data
• can be overridden in the derived class
– the parent’s methods/data are only hidden but still accessible (using super)
• Dynamic binding for polymorphism
– when a method is called, a search takes place at the child’s
location for that method’s definition
– if not found, the search continues up the hierarchy until the
method’s definition is found (if none found, error)
• if parameters and return type are the same for all classes that a
polymorphic variable can take on, then type checking can be done at
compile time, otherwise it is done at run-time
Smalltalk Messages and Methods
• All items in Smalltalk are objects, so all operations
are methods and specifying actions is done strictly
through message passing (even if it doesn’t look
like it!)
– messages contain
• object for whom the message is sent
• method to invoke
• any needed parameters
– some examples:
• 21 + 2 // object 21 receives message + and parameter
2
• sum / count //sum receives message to divide by count
• firstArray at: 1 put: 5 // firstArray gets message at with
// parameter 1 and put 5, or
// firstArray[1] = 5;
• ourPen home; up; goto: 500@500; down; home
Message Types Continued
• 3 forms of methods:
– unary methods (message without params)
– binary methods (as with 21 + 2 or sum / count,
mostly used for arithmetic operations)
– and the general form shown below where key# is a
keyword for the object
• key1: param1 key2: param2 … key n: param n
• Assignments statements operate as follows
– any message expression, variable or literal object on
RHS
– LHS is a data instance
• total  22
• sales  deducts grossPay: 350.0 dependents: 4
Defining a Class
• Much like Java, you define your class, its variables
and its methods
– In Smalltalk, you have class variables and instance
variables
• class variables are like Java’s static instance variables – that is,
you define a variable to be classwide
– The notation is:
• Object subclass: #superclassname
– instanceVariableNames: ‘’
– classVariableNames: ‘’
– poolDictionaries: ‘’
– Category: ‘classname’
– If you have variables to define in any section, separate
them by spaces within the ‘’ as in ‘x y z’
• the poolDictionary contains variables that are not owned by
this class, so you can use this to define global variables that
this class might manipulate – bad idea of course!
Defining Methods
• Since Smalltalk is interpreted, you typically define
your methods interactively after you have defined
your class rather than wrap them up in a single
definition
– Methods by default do not expect to receive parameters
– If you want your method to receive a single parameter,
add : param after the method’s name as in
• setX: newValue
– If you have multiple parameters, you must have specific
keywords for all but the first as in
• setValues: val1 Value2: val2 Value3: val3
– In this case, you would call the method as setValues: 5 Value2: 3
Value3: 10
– Local variables are declared in | | notation as in | x y z |
– To return a value at the end, use ^ returnvalue
Object subclass: #NameOfSubclass
instanceVariableNames: ‘p1 p2'
classVariableNames: ''
poolDictionaries: ''
category: 'Point‘
Example: Point
getP1
^p1.
Here is how we can interact with Points:
getP2
point1 := Point new.
^p2.
point1 init: 5 second :10.
init: x second: y
point2 := Point new.
p1:=x.
point2 init: 12 second :7.
p2:=y.
point1 distance: point2.
distance: point2
| temp1 temp2 |
temp1:=(p1 - point2 getP1)*(p1 – point2 getP1).
temp2:=(p2 - point2 getP2)*(p2 – point2 getP2).
^ (temp1 – temp2) sqrt.
Blocks and Control Structures
• Blocks are specified in [ ] with instructions separated by .’s
– block code is only executed when the message value is sent to the block
• addIndex  [sum <- sum + index]
• addIndex value
• value is a message to addIndex to execute the block
• Blocks can contain relational expressions and return True or
False providing a mechanism for conditional blocks
– conditional blocks can be used to form a pretest loop method called
whileTrue:
• x  1. sum  0. [x <=20]
whileTrue: [sum  sum+x. xx+1]
– another loop is timesRepeat: which is provided an integer value
• Selection statements use ifTrue and ifFalse as in
– [x > 0] ifTrue: [y  x + 1. x  x – 1] ifFalse: [y  0.]
Evaluation of Smalltalk
• Small language, simple (?) syntax
– mathematically limited
– less efficient than imperative languages
– because of dynamic type checking, errors often not caught until run-time
• First real OOPL and the only pure OOPL until Ruby
– successor languages did not like to force everything to be message passing
and therefore most OOPLs are hybrids of some form
• Smalltalk pioneered many of the ideas found common in all
OOPLs
– LOGO was a system built using Smalltalk to provide a graphical
programming environment
• objects are windows, menus, cursor, lines, …
• messages include down, up, turn:degrees, go:distance, goto: point, home,
north, …
• Pen is the general class designated to draw
• To draw a triangle:
– OurPen Pen new defaultNib: 2.
– OurPen up; goto: 800@300; down
– OurPen go: 100; turn: 120; go: 100; turn: 120; go: 100
C++
• Based on C (same types) but adds classes
– updates Smalltalk’s object system as follows:
• classes can either be a derived class (from a superclass) or stand alone
without having a superclass
• some or all data and functions can be inherited from base class(es)
• objects can be either stack dynamic or heap dynamic (these require a
destructor method to deallocate memory)
– both forms require a constructor
– whereas Smalltalk’s use of classes was consistent and fairly
simple (because the language itself was small), C++’s use of
classes is very complex and the language is quite large
• C++ is the most used OOPL in spite of (or maybe
because of) having complex object-oriented mechanisms
– such as multiple inheritance and complete flexibility in
controlling what is inherited
Controlling Inheritance
class base_class {
• Class members can be private:
private, protected or int a; float x;
public protected:
int b; float y;
– private members are only public:
accessible by member int c; float z; }
functions and friends of
the class class sub1 : public base_class {…};
• friends are class sub2 : private base_class {…};
functions/classes
explicitly declared as in sub1: b and y are protected, c and z are public
friends by the given class
in sub2: b, y, c and z are private and no derived
– public members are class of sub2 will have access to any of these
accessible by any function
– protected members are a and x are not accessible to sub1 or sub2
like private members
note that since sub2 is a derived private class, no member
except that derived classes of the parent class is explicitly visible, and so b, c, y and z
can modify access rights must be re-exported to be used in an instance of sub2 –
for inheriting members this is done using : : as in base_class : : c;
Example
class single_linked_list { class stack : public single_linked_list {
class node { public:
friend class single_linked_list; stack( ) { }
private: void push(int value) {
node *link; single_linked_list::insert_at_head
int contents; (int value);
}; }
private: int pop( ) {
single_linked_list( ) {head = 0}; single_linked_list::remove_at_head( );
void inset_at_head(int); }
void insert_at_tail(int); };
int remove_at_head( );
int empty( ); class queue : public single_linked_list {
}; public:
queue( ) { }
The nested inner class, node, lists void enqueue(int value) {
single_linked_list as a friend so that single_linked_list::insert_at_tail
single_linked_list can access node’s private parts (int value);
}
int dequeue( ) {
Both stack and queue extend single_linked_list::remove_at_head( );
single_linked_list but both are public }
derivations, we should restrict that by };
making them private – see the code on
Page 540-542
C++ Object Binding
• Objects can be referenced through ordinary variables
– these objects are stack dynamic and all method calls would be
statically bound
• Otherwise, objects are referenced via pointers
– these objects are heap dynamic
– any pointer of a class can point at any derived class of that
class
• thus, pointers can be polymorphic variables
• but non-pointers cannot
– if the variable is polymorphic then method calls are
dynamically bound
– any method that will be dynamically bound must be declared
as a virtual function
Example
public class shape {
public:
virtual void draw( ) = 0; // indicates that draw is a pure virtual function
} // that is, that there is no implementation here
// so shape is an abstract class
public class circle : public shape {
public:
virtual void draw( ) {…} square s; // s is dynamically
} rectangle r; // bound to draw
shape &ref_shape = s;
public class rectangle : public shape { ref_shape.draw( ); // whereas r is statically
public: r.draw( ); // bound to draw
virtual void draw( ) {…}
}

public class square : public rectangle {


public:
virtual void draw( ) {…}
}

Java
Most of you are familiar with Java, so we will only cover a few highlights of
objects in Java
– all entities in Java are objects except for the primitive types so all Java
programs require class definitions
• the class with the main method is an object that creates or calls upon all other
objects
– Java restricts inheritance to single inheritance
• all objects must have a parent (no stand-alone objects), by default, the parent is
Object
• multiple inheritance can somewhat be simulated through interfaces
– all objects are heap dynamic and pointed to by reference variables (a
pointer that does not require dereferencing)
– all method calls are dynamically bound (unless a class is denoted as final
which means it can not be extended, so it will not have subclasses)
– Java includes a finalize method that will be invoked before the object’s
memory is returned to the heap
• Java has no destructor since garbage collection is used
– Java is simpler and less powerful than C++
• but that might be a good thing!
C#
• C# offers constructs for the class (similar to Java) and
struct (similar to C++)
– structs are stack dynamic, objects are heap dynamic
– C#’s syntax is more like C++ for class definitions, for
example:
• public class NewClass : ParentClass {…}
– dynamic binding is done only if methods are specially
indicated as virtual where overridden methods in derived
classes must be specially indicated through the word override
• classes that contain abstract methods must be declared as abstract and
abstract classes cannot be instantiated (see page 534 for example)
– like Java, C# offers only single inheritance and all classes
must have a parent (no stand-alone classes) with the parent
class defaulting to Object
• the Object class implements ToString, Finalize and Equals, which are
inherited to all classes
Objects in Ada 95
• Ada 83 included the Package for encapsulating ADTs
– Objects were added for Ada 95 as an extension for this
– Objects became a new type called a tagged type
– Tagged types are either records or private types
• private types are true objects as they offer information hiding
– Packages can be separately compiled giving Ada 95 the ability to offer
classes much like Java, C++, and C#
• Ada offers both static and dynamic binding of objects to
procedure calls
– Dynamic binding is available through the tagged type’s classwide type
denoted as Name’class or by using a polymorphic variable
• Ada objects:
– No implicit calling of constructors and destructors
• if desired, they must be invoked explicitly, but they are not needed
– Single inheritance
• although multiple inheritance can be simulated to some extent using generic
classes
– Subclasses inherit all items from a parent class and to restrict this, you
would have to use child library packages (nested directly inside of the
parent’s package)
Ada Example
Package PERSON_PKG is
type PERSON is tagged private; P : PERSON;
procedure DISPLAY(P : in out PERSON);
private S : STUDENT;
type PERSON is tagged Pcw : PERSON’class; // classwide
record … // version of Person
NAME : STRING(1..30); DISPLAY(P); // call Person’s display
ADDRESS : STRING(1..30);
AGE : INTEGER; DISPLAY(S); // call Student’s display
end record; Pcw := P;
end PERSON_PKG; DISPLAY(Pcw); // Person’s display
Pcw := S;
with PERSON_PKG; use PERSON_PKG;
Package STUDENT_PKG is DISPLAY(Pcw); // Student’s display
type STUDENT is new PERSON with
record
GRADE_POINT_AVERAGE : FLOAT;
GRADE_LEVEL : INTEGER; Ada’s mechanisms for objects is
end record; built on top of previous mechanisms
procedure DISPLAY (ST: in STUDENT);
end STUDENT_PKG; and so is both awkward and less
flexible than C++, and inconsistent
Note: DISPLAY is being overridden from person_PKG as compared to Java/C#
Ruby
• Like Smalltalk, everything in Ruby is an object and all
computation is done via message passing
– class definitions are executable, meaning that a class’
definition (structure or available methods) can change at run
time
• for instance, you could have code that modifies a class at run-time so
that the class gains a new method
• at run-time, a class is the union of all definitions that have been
executed
– all variables are reference variables to objects and all are
typeless
• instance variable names are denoted by starting with @
• instance variables are always private (accessor methods must be
written if you want to provide external access to an instance variable)
– methods default to public, but can be private or protected
– accessor/mutator methods can be easily generated by using
the shortcut functions attr_reader and attr_writer respectively
• for instance: attr_reader :member1, :member2 will automatically
generate a getter method to return the value of member1
More on Ruby
• Deriving a subclass is done through < as in
– class subclass < parentclass
– access control to methods can be changed at the subclass level (for
instance, if subclass above inherits method foo, subclass can alter the
access control from public to private or protected)
• The Ruby module is used to control encapsulation and
namespaces
• All variables are polymorphic (they are typeless and so only
bound to a given object when assigned to point at it) and are
therefore dynamically bound to methods
• While Ruby is a pure OOPL (and therefore will satisfy some OO
programmers), it is generally a weaker language than C++, Java
or C# in that it lacks the ability to more tightly control
– what is inherited and how (no multiple inheritance)
– access control
– other OOPL features like abstract classes
JavaScript
• JavaScript – primarily use is for dynamic html pages
• JavaScript is similar to Java in syntax and
– JavaScript, like Java, uses two types of data
• objects and primitive data types
– but from there, the treatment of objects differs:
• Java: statically typed language
• JavaScript: dynamically typed language with all variables being
reference variables (implicit pointers) much like in Lisp
• JavaScript: does not have a class, objects are created dynamically
without a formal definition
– so JavaScript does not support inheritance or polymorphism
• JavaScript does not require that variables be declared, but even if they
are, they do not have to be typed
– types are determined when the variable is assigned a value, and the type
changes as the value assigned changes (much like Lisp)
– any variable can reference any primitive type or any object
JavaScript Objects
• Objects have a collection of properties
– These properties are their data members and methods
• each data member is a pair
– the name and its current value
• functions and methods are objects themselves and referenced by
variables which point to them
• to create an any object, new is used, creating a blank object
– example: var my_object = new Object( );
• to add to an object, assignment statements are used
– example: my_object.name = “Frank Zappa”; and my_object.occupation =
“musician”;
– objects can be nested by now doing my_object.education = new Object( );
and assigning my_object.education.college = “none”;
– if access is made to a property that does not exist, the value undefined is
returned
• to remove from an object, use delete as in delete my_object.occupation;
More on JavaScript
• Functions/methods are defined • JavaScript is like Java in that it
contains
similar to properties: – most of the same control structures as
– define the function Java
• function f( ) {…} – the same arithmetic operators as Java
and the same style of assignment
– assign a variable to point at the statement
function – many of the same String operations as
Java
• var x = f
• JavaScript is not intended for
– constructors are defined as ordinary
large-scale applications
functions and called (if defined) – so this primitive and flexible
whenever new is used treatment of objects is satisfactory if
• example: you need objects in your script
• but if you want to do OOP, you would
• function musician(style, instrument, never choose JavaScript
age) {this.style = style;
this.instrument = instrument;
this.age = age);}
• my_object = new musician(“rock”,
“guitar”, 37);
Implementing Objects
• To implement an object, there needs to be at least two
mechanisms available for easy construction and use:
– a description of the data storage needed for the object
– pointers to the object’s methods so that, if dynamically bound, the method
call can quickly be made
• Both of these can be captured by having the compiler generate a
class instance record (CIR) at compile-time
– any newly instantiated object uses the CIR as a template to generate the
storage space needed for the object
– the CIR could contain a pointer to all methods, but either the CIR would
have to modified at run-time whenever the variable is altered to point at a
subclass (if the variable is polymorphic), or we would have to disallow
polymorphic variables – so we will use a different approach
• instead, we might use a virtual method table for each class – this will differ for
a subclass
• the CIR then points at the VMT for the class it is currently assigned to, and this
pointer changes whenever the variable is assigned to a different class
public class A {
Example of CIRs
public int a, b;
public void draw( ) {…}
public int area( ) {…}
}

public class B extends A {


public int c, d; This becomes more complicated if multiple
public void draw( ) {…} inheritance is allowed, see figure 12.3 on page
public void sift() {…} 563 to illustrate this in C++
}

You might also like