9. Object Oriented Programming

9.1. What is “Object Oriented”?

9.1.1. “Object oriented” as a paradigm

We usually make a model when solving a real-world problem. The model is called object oriented if the model consists of something called objects and these objects interact with each other.

  • By using objects, we can divide a task into several encapsulated sub-tasks.

  • The object oriented paradigm is not only used in programming but also applicable to the whole software development process such as the object oriented design.

9.1.2. Object oriented languages

Many people use the term object oriented languages in various different ways. One of the broadest definitions is the following two conditions:

  • There is a unit called object that performs some calculation and stores some data.

  • A message is passed from one object to another.

This definition requires neither class nor dynamic creation of objects.

Other (narrower) definitions include more conditions, some of which are:

  • Objects are created dynamically.

  • Objects are abstract data types.

  • Objects can inherit functions of other objects.

9.2. Abstract data type

An abstarct data type is a type that has following properties:

  • From outside, we cannot say how data are actually represented and stored.

  • The only available operations from outside are subprograms given by the abstract data type.

The two properties above provide abstarction of data structures; modificatin inside an abstract data type does not affect outside. This is also called encapsulation or information hiding.

Package in Ada

At the time Ada was designed, there was no such thing as Internet. It was very important to support development of a large program by dividing it to several modules which were developed in different places.

  • package is the unit of encapsulation.

  • A package consists of a specification package and a body package of the same name.

  • A specification package contains interface information. When compiling, only specification package is required to use that package.

Though a specification package is basically a public information, a private part can be declared in a specification package so that type information is available for only compilers, not programmers.

package Stack_Pack is
  -- public part
  type Stack_Type is limited private;
  function Empty(S : in Stack_Type) return Boolean;
  procedure Push(S : in out Stack_Type; Element : in Integer);
  procedure Pop(S : in out Stack_Type);
  function Top(S : in Stack_Type) return Integer;
  -- private part
  private
    Max_Size : constant := 100;
    type Stack_Type is
      record
      List : array ( 1 .. Max_Size ) of Integer;
      Top_Index : Integer range 0 .. Max_Size := 0;
      end record;
  end Stack_Pack

9.3. Designing object oriented languages

9.3.1. How pure the language is object oriented?

It is possible to represent every data as an object and every operation as a message. However, it may be inefficient to implement operations such as 1+2 with objects and messages.

  • In C++ and Java, primitive data are not objects.

  • In Ruby, all the data are objects, but control structures such as while and if are not messages.

  • In Smalltalk, everything is an object, and every operation (except assignment and return) is a message.

New methods for integers in Ruby

class Integer
  def foo
    self + 100
  end
end

1.foo  # => 101

Conditional branch in Smalltalk

"Push an element into the stack"
push: anElement
  self isFull ifTrue: [ self error: 'stack full' ]
              ifFalse: [ top <- top + 1.
                         elements at: top put: anElement ]

metaclass

Since everything is an object in Ruby and Smalltalk, a class is also an object. For example, sending a message new to a class creates a new instance.

Since every object has a class that defines the behavior of the object, a class has also a class called metaclass that defines the behavior of the class.

Since everything is an object, a metaclass is an object.

Since every object has a class that defines the behavior of the object, a metaclass has also a class that defines the behavior of the metaclass.

Since everything is an object, a class of metaclass is an object.

Since every object has …

9.3.2. Class-based or prototype-based?

class-based

  • There is a class that defines attributes or behavior of objects.

  • It is possible to create more than one instances from a class where all instances share the definition of the class.

  • Inheritance is a mechanism to share attributes and behavior among more than one classes.

  • Many languages such as Smalltalk, C++, Java, Ruby, etc.

prototype-based

  • Each object has a reference to another object called prototype.

  • When a object is requested some attributes the object does not posses, the object asks for its prototype. If the prototype does not posess those attributes either, it further asks for its prototype. This mechanism is called delegation.

  • Languages such as Self, JavaScript.

9.3.3. What kind of information hiding is possible?

It is usually a good idea to encapsulate data stored in an object. However, it is sometimes convenient to allow access from outside.

Controlling Access in Smalltalk

  • No Instance variables can be accessed by other objects.

  • All methods are accessible from any other object.

Controlling Access in C++

  • public : accessible from any class.

  • protected : accessible from subclasses and friends.

  • private : accessible from friends only.

Controlling Access in Java

Package is another unit of information hiding.

  • public : accessible from any class.

  • No modifiers : accessible from classes in the same package.

  • protected : accessible from subclasses.

  • private : not accessible from any other class.

9.3.4. Single inheritance or multiple inheritance?

single inheritance

Each class has only one superclass.

multiple inheritance

A class may have more than one superclasses.

Obviously, multiple inheritance is more powerful than single. However, some people think multiple inheritance is hard to use because its semantics is very complicated.

9.3.5. Specification inheritance or implementation inheritance?

Specification inheritance

Only a public part of superclass is accessible from its subclasses.

Implementation inheritance

All parts of superclass (including internal structure) is accessible from its subclasses.

Implementation inheritance allows programmers to reuse code in a superclass. However, it is not good for encapsulation because modificaton of superclass may affect subclasses.

Inheritance in Java

  • extends : single implementation inheritance

  • implements : multiple specification inheritance

9.3.6. How types are checked?

In typed object oriented languages, a class is usually a type. Since a subclass represents a subset of its superclass, it is natural to define a subclass as a subtype of its superclass (i.e. the subclass type can be substituted for the superclass type).

Type checking in Java

public class A {
    public static void main(String args[]) {
        A x = new B();    //OK
        B y = new A();    //Error at compile time
        B y = (B)new A(); //Error at runtime
    }
}

class B extends A {
}

Exercise 18

In the example above, B y = new A(); is prohibited while A x = new B(); is permitted.

Explain what kind of inconvenience would occur if B y = new A(); was permitted.

[Answer]

9.3.7. Early binding or late binding?

When a method in a superclass is overridden by a method in a subclass, we need to decide which method definition will be used.

  • Early binding (or static binding): methods to be called are fixed before execution by using type information. Faster execution.

  • Late binding (or dynamic binding): methods to be called are determined at runtime. More flexible.

Virtual functions in C++

  • Default is early binding.

  • A function with virtual uses late binding.

class Bird {
public:
  bool fly() { return true; }
};

class Penguin : public Bird {
public:
  bool fly() { return false; }
};

int main() {
  Bird *x;
  Penguin *y;

  y = new Penguin();
  x = y;
  x->fly() // true
  y->fly() // false
}

In case of Java

  • Default is late binding.

  • A method with final uses early binding because it cannot be overridden by subclasses.