Chapter 10 Object-Oriented Programming Software Reuse and Independence Objects, Classes, and Methods Inheritance and Dynamic Binding Language Examples: Java, C++, Smalltalk Design Issues and Implementation Issues
Why Objects? Benefits of Object-Oriented Programming Dynamic Control The exact behavior of functions are determined according to the object itself. Code Reuse The behaviors of objects can be redefined or extended based on the previous behaviors. Independent Modifiability Redefinition of behaviors does not incur the recompilation of the previous codes. Some languages, such as Smalltalk, allow behavior to change even during execution! Programming Languages 2
Fundamental Concepts Classes and Methods The class is an ADT mechanism that additionally offers good initialization control (constructors). Inheritance A class can extend another class (it becomes a subclass), thus enabling the reuse of all (or some) of the previouslywritten code. Dynamic Binding A variable of a class can contain an object of a subclass, and all subclass-modified behavior automatically applies. Programming Languages 3
Objects and Classes Object an abstraction of real world objects an object is consisted of the state: defined by variables (instance variables) the behavior: defined by functions (methods) Class a blueprint for a set of objects the objects of a class is called instances of the class The True Story The class concept is devised to share the methods of similar objects. Programming Languages 4
Class Complex in Java public class Complex { public Complex() { re = 0; im = 0; public Complex (double realpart, double imagpart) { re = realpart; im = imagpart; public double realpart() { return re; public double imaginarypart() { return im; public Complex add( Complex c ) { return new Complex(re + c.realpart(), Special methods called constructors. The first constructor is a default constructor which takes no parameters Private entities are inaccessible from the client codes. im + c.imaginarypart()); public Complex multiply (Complex c) { return new Complex(re * c.realpart() - im * c.imaginarypart(), re * c.imaginarypart() + im * c.realpart()); private double re, im; The declaration of instance variables Programming Languages 5
Using the Complex Class public class ComplexUser { public static void main(string[] args) { Complex z,w; z = new Complex (1,2); w = new Complex (-1,1); z = z.add(w).multiply(z); System.out.println(z.realpart()); System.out.println(z.imaginarypart()); A method add of the object z is invoked. (A message add(w) is sent to z.) The object w is a parameter of the method. Creating Complex objects. Complex constructors are invoked. Programming Languages 6
Complex Using Polar Coordinates public class Complex { public Complex() { radius = 0; angle = 0; public Complex (double realpart, double imagpart) { radius = Math.sqrt(realpart*realpart + imagpart*imagpart); angle = Math.atan2(imagpart,realpart); public double realpart() { return radius * Math.cos(angle); public double imaginarypart() { return radius * Math.sin(angle); public Complex add( Complex c ) { return new Complex(realpart() + c.realpart(), imaginarypart() + c.imaginarypart()); public Complex multiply (Complex c) { return new Complex(realpart() * c.realpart() - imaginarypart() * c.imaginarypart(), realpart() * c.imaginarypart() + imaginarypart() * c.realpart()); private double radius, angle; Note that the public interfaces are not changed! Programming Languages 7
Inheritance A class B may be designed by extending an existing class A public class B extends A {... In this case, A is called the superclass of B and B is called the subclass of A B inherits all the instance variables and methods of A This makes an is-a relation: B is-a A When the classes are treated as types, B is a subtype of A and A is a supertype of B Subtype Principle An object of a subtype may be sued anywhere an object of its supertype is legal Programming Languages 8
The Object Class in Java The Class Object The topmost class in the Java class hierarchy All classes implicitly extend the class Object public class A {... means public class A extends Object {... Overriding the Methods The methods of a superclass may be customized for a subclass. This redefinition of methods is called overriding Let s override some methods in the Object class Programming Languages 9
Class Complex in Java public class Complex { //... previous code as before // Must keep Object class definition for overriding public boolean equals (Object obj) { Complex c = (Complex) obj; return re == c.realpart() && im == c.imaginary part(); public String tostring() { return re + " + " + im + "i"; The methods equals and tostring are overridden. Downcasting: if obj is not a Complex object, runtime error will be occurred. Complex z = new Complex(1,1); Complex x = new Complex(1,1); if (x.equals(z)) System.out.println("ok!"); System.out.println(z); The result of the above code will be: ok! 1.0 + 1.0i Programming Languages 10
Abstract Class and Abstract Methods Abstract Method a method whose implementation is not defined AKA deferred method abstract methods should be overridden Abstract Class a class which contains a abstract method an abstract class cannot have instances public abstract class ClosedFigure { public ClosedFigure (Point c) { center = c; //... public abstract double area(); private Point center; Programming Languages 11
Subclasses of ClosedFigure Class public class Circle extends ClosedFigure { public Circle( Point c, double r) { super(c); radius = r; //... public double area() { return Math.PI * radius double * h) radius; { super(c); private double radius; width = w; public class Rectangle extends ClosedFigure { public Rectangle (Point c, double w, height = h; //... public double area() { return width * height; Invoke the constructor of the superclass private double width; private double height; Programming Languages 12
Using the ClosedFigure Classes public class User { public static void main(string[] args) { Point x,y; ClosedFigure f; Rectangle r; Circle c; x = new Point(0,0); y = new Point(1,-1); r = new Rectangle(x,1,1); c = new Circle(y,1); f = r; System.out.println(f.area()); f = c; System.out.println(f.area()); Dynamic Binding Note that the dynamic binding of the method invocations The 1 st call to f.area() calls the method of r The 2 nd call to f.area() calls the method of c Programming Languages 13
Inheritance Graph Inheritance graphs show the superclass-subclass relationship AKA class diagram Example ClosedFigure Rectangle Circle Programming Languages 14
Multiple Inheritance Multiple Inheritance a class inherits from two or more superclasses Repeated Inheritance Problem the subclass object may have multiple copy of multiply inherited class objects. A A A B C B C D D Programming Languages 15
Multiple Inheritance in Languages Java Java does not support the multiple inheritance of classes. Java supports multiple inheritance of interfaces. An interface is similar to an abstract class where all the methods are abstract and implicitly public. An interface can be used as a type name. C++ C++ supports multiple inheritance of classes. The repeated inheritance problem is controlled by virtual inheritance. Programming Languages 16
Interface Example public interface LinkableObject { LinkableObject next(); void linkto( LinkableObject p); public class LinkableComplex extends Complex implements LinkableObject { private LinkableObject link; public LinkableObject next() { return link; public void linkto( LinkableObject p) { link = p; public LinkableComplex( double re, double im) { super(re,im); link = null; The class LinkableComplex is a subclass of Complex with additional functionality of the interface LikableObject. Programming Languages 17
Polymorphism in Java Ad-hoc Polymorphism (Overloading) Java supports overloading of methods Subtype Polymorphism Java supports subtype polymorphism using dynamic binding of method invocations Parametric Polymorphism Currently, Java does not support parametric polymorphism, such as template. Parametric polymorphism can be simulated basedobject approach Programming Languages 18
LinkableObject (in Java) public class LinkableObject { public LinkableObject( Object d ) { link = null; item = d; public LinkableObject( Object d, LinkableObject link) { this.link = link; item = d; public LinkableObject next() { return link; public void linkto( LinkableObject p) { link = p; public Object data() { return item; private LinkableObject link; private Object item; Note that a LinkableObject may link arbitrary Object. Programming Languages 19
Queue (in Java) public class Queue { public Queue() { rear = null; public boolean empty() { return rear == null; public LinkableObject front() { return rear.next(); public void dequeue() { if (front() == rear) rear = null; else rear.linkto(front().next()); public void enqueue( LinkableObject item) { if (empty()) { rear = item; rear.linkto(item); else { item.linkto(front()); rear.linkto(item); rear = item; private LinkableObject rear; The class Queue is designed using the class LikableObject in order to link any kind of objects. Programming Languages 20
Based-Object Approach LinkableObject r = new LinkableObject(new Double(1.2)); LinkableObject i = new LinkableObject(new Integer(42)); LinkableObject c = new LinkableObject(new Complex(1,-1)); Queue q = new Queue(); q.enqueue(r); q.enqueue(i); q.enqueue(c); q.dequeue(); System.out.println(q.front().data()); // prints 42 Based-object approach may need RTTI (run-time type identification): Object obj = q.front().data(); if (obj instanceof Double) System.out.println(((Double)obj).doubleValue()*2); else if (obj instanceof Integer) System.out.println(((Integer)obj).intValue()*2); else if (obj instanceof Complex) System.out.println(((Complex)obj).add((Complex)obj)); Programming Languages 21
Dynamic Nature of Objects Object Allocation and Deallocation Fully Manual Fully Automatic Hybrid: manual allocation and automatic deallocation Method Invocation Static Binding: methods are invoked according to the class of object variable Dynamic Binding: methods are invoked according to the actual receiver object of the message Programming Languages 22
Dynamic Binding Example class A { void p() { System.out.println("A.p"); void q() { System.out.println("A.q"); void f() { p(); // interpreted as this.p(); q(); // interpreted as this.q(); The program prints: class B extends A { void p() A.p { System.out.println("B.p"); void q() A.q The 1st a.f() call { System.out.println("B.q"); B.p super.q(); B.q The 2nd a.f() call A.q public class VirtualExample { public static void main(string[] args) { A a = new A(); a.f(); a = new B(); a.f(); Programming Languages 23
C++ A complex, multiparadigm language. Has almost every conceivable feature. Some of its problems are inherited from C. Programs can be very fast and concise. For OO programming, problems come from (not in order of importance): Multiple inheritance Operator overloading Lack of garbage collection Interaction with templates Focus on execution speed Inadequate standard library Programming Languages 24
Defining Classes in C++ Different Terms in Different Languages C++ Community Java Community base class derived class member function member variable superclass subclass method instance variable Class declaration and definition may be separated To define a member function outside of a class, use the scope resolution operator. The member functions defined inside of a class are automatically regarded as inline functions Programming Languages 25
LinkableObject (in C++) class LinkableObject { public: LinkableObject() : link(0) { The initializers are used to ensure that the instance variables are initialized prior to the execution of the body of the constructor. LinkableObject (LinkableObject* p) : link(p) { LinkableObject* next() { return link; void linkto (LinkableObject* p) { link = p; The access modifiers (public, private: private, etc.) are not applied for LinkableObject* link; every member. Rather, they ; declare sections. The default section is private. Programming Languages 26
Queue Declaration (in C++) class Queue { public: Queue() : rear(0) { bool empty() { return rear == 0; implicitly inline but not always void enqueue(linkableobject* item); void dequeue(); LinkableObject* front() { return rear->next(); ~Queue(); protected: // demo - may not be appropriate LinkableObject* rear; ; Programming Languages 27
Queue Methods (in C++) void Queue::enqueue(LinkableObject* item) { if (empty()) { rear = item; rear->linkto(item); else { item->linkto(front()); rear->linkto(item); rear = item; void Queue::dequeue() { if (front() == rear) rear = 0; else rear->linkto(front()->next()); Queue::~Queue() // demo code - may result in dangling refs { while (!empty()) { LinkableObject* temp = front(); dequeue(); delete temp; Note that the scope resolution operators are used. Currently, LinkableObject objects contains no data. Define a derived class of LikableObject to store any useful data. Programming Languages 28
LinkableInt (in C++) class LinkableInt : public LinkableObject { public: LinkableInt(int d) : item(d) { int data() { return item; private: int item; ; The Queue can be used as following:... Queue q; LinkableInt* x = new LinkableInt(42); q.enqueue(x); x = static_cast<linkableint*>(q.front()); cout << x->data() << endl; // prints 42... Programming Languages 29
Parametric Polymorphism in C++ C++ supports every kinds of polymorphism C++ supports overloading (ad-hoc polymorphism) C++ supports inheritance (subtype polymorphism) C++ has template (parametric polymorphism) What about based-object approach? C++ has no top-most class based-object approach may be simulated using generic pointers (void* pointers) but generic pointers do not support dynamic binding Programming Languages 30
Template Queue (in C++) template<typename T> class Queue { public: Queue() : rear(0) { int empty() { return rear == 0; void enqueue (T item); void dequeue (); T front() { return rear->next->data; ~Queue(); protected: class Linkable { public: T data; Linkable* next; ; Linkable* rear; ; Class Linkable is declared as a nested class. Programming Languages 31
Template Methods (in C++) template <typename T> void Queue<T>::enqueue(T item) { Linkable* temp = new Linkable; temp->data = item; if (empty()) { rear = temp; rear->next = temp; else { temp->next = rear->next; rear->next = temp; rear = temp; template <typename T> void Queue<T>::dequeue() { Linkable* temp = rear->next; if (temp == rear) rear = 0; else rear->next = rear->next->next; delete temp; template <typename T> Queue<T>::~Queue() { while (!empty()) dequeue(); The methods should be defined as template functions because the class Queue is declared to take a type parameter T. The Queue may be used as following (Notice that the type parameter is given):... Queue<int> q; q.enqueue(42); int x = q.front(); q.dequeue();... Programming Languages 32
Dynamic Binding in C++ class A { public: void p() { cout << "A::p\n" ; virtual void q() { cout << "A::q\n" ; void f() { p(); q(); ; class B : public A { public: void p() { cout << "B::p\n" ; void q() { cout << "B::q\n" ; ; int main() { A a; B b; a.f(); b.f(); a = b; a.f(); The program prints: A::p A::q A::p B::q A::p A::q The 1st a.f() call The b.f() call The 2nd a.f() call Programming Languages 33
Virtual Functions Virtual functions support dynamic binding The virtual property of a member function is also inherited (i.e. the function which overrides a virtual function is implicitly virtual) Pure virtual function is an abstract function class ClosedFigure // an abstract class { public: virtual double area() = 0; // pure virtual... ; Programming Languages 34
Controlling Multiple Inheritance C++ supports two kinds of inheritance Shared Inheritance Repeated Inheritance A A A B C B C D D To get shared inheritance, use the keyword virtual when deriving a class: class A {...; class B : virtual public A {...; class C : virtual public A {...; class D : public B, public C {...; This is the default. Programming Languages 35
Smalltalk Ahead of its time: consistent design and rich library. Dynamic (like Lisp): variables have no specified type. The class structure is the type system. Everything is an object, including numbers. So somewhat lacking in efficiency. There are no explicit protection markers: all data is implicitly private, all methods implicitly public. Syntax is peculiar, and tied to the runtime environment. Typically only a global namespace for classes, so I will call the example class MyPoint. Programming Languages 36
Smalltalk Brief History due to Alan Kay at Xerox PARC (early 1970s) arose out of a research project (Dynabook Project) Features purely object-oriented (everything is an object) dynamic (dynamic binding and dynamic memory management) tightly coupled with the runtime environment implicit protection (all data are private, all methods are public) peculiar syntax (see the next slide) Programming Languages 37
Some Notes on Smalltalk Syntax Method names are called selectors unary selector q front means q.front() in C++ or Java keyword selector table insert: anitem at: anindex means table.insert(anitem,anindex) in C++ or Java binary selector: one or two symbols 2 + 3 + 4 means (2.+(3)).+(4) Arrows for return and assignment upward arrow ( or ^) denotes a return left arrow ( or <-) denotes an assignment Programming Languages 38
Class Definition Syntax Class name: <name> Superclass: <name> Instance variables: <list-of-names> Methods: <name> <implementation> <name> <implementation> Programming Languages 39
LinkableObject Class (in Smalltalk) Class name: LinkableObject Superclass: Object Instance variables: link Methods: next Two methods, next and linkto, ^ link are defined. linkto: anobject link <- anobject Class Method: new: alinkableobject ^ (self new) linkto: alinkableobject overriding the default new method of the metaclass Class Programming Languages 40
local variable Queue Class (in Smalltalk) Class name: Queue object identity test Superclass: Object Instance variables: rear Methods: empty ^ rear == nil front ^ rear next enqueue: alinkableobject self empty iftrue: [ rear <- alinkableobject. code block rear linkto: rear ] iffalse: [ alinkableobject linkto: rear next. rear linkto: alinkableobject. rear <- alinkableobject ] dequeue temp temp <- self front. statement delimiter (rear == temp) iftrue: [ rear <- nil ] iffalse: [ rear linkto: (temp next) ] Programming Languages 41
Test Code for Queue (in Smalltalk) q <- Queue new. x <- LinkableObject new. y <- LinkableObject new. q enqueue: x. q enqueue: y. y <- q front. "now y == x" q dequeue. q dequeue. "now q is empty" Programming Languages 42
Implementation Issues Implementing Object Allocation similar to normal record implementation subclass objects need more space than superclass ones Implementing Dynamic Binding Naïve Implementation search the entire class hierarchy during runtime Advanced Implementation construct a method table during compile time a fixed offset can be statically determined for each method attach the pointer of the table to corresponding objects for each object creation Programming Languages 43
Object Allocation The following implementation allows in-place overwrite of subclass objects by superclass objects. class Point {... private double x,y; class ColoredPoint extends Point {... private Color color; Point object space for x space for y coloredpoint object space for x space for y space for color Programming Languages 44
Virtual Method Table The VMT (virtual method table) pointer is attached to each objects Assume that Class Point has only one method moveto Class ColoredPoint has only one method getcolor Point object VMT for Point coloredpoint object VMT for coloredpoint VMT pointer moveto VMT pointer moveto space for x space for y space for x space for y space for color getcolor Programming Languages 45