Top Banner
Object Oriented Programming Chapter 13
53

Chapter 13. Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Dec 22, 2015

Download

Documents

Miles Wilkinson
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Object Oriented Programming

Chapter 13

Page 2: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Imperative program design is based on procedural abstraction and functional decomposition◦ Procedural abstraction: supports reusable code

through libraries of functions. Programmers can think in terms of interfaces and functionality: what does it do instead of how does it do it?

◦ functional decomposition (stepwise refinement): systematically refines the problem into smaller and smaller parts until the functions are small enough to represent in primitive language statements.

13.1: Abstract Data Types

Page 3: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Extends the idea of procedural abstraction to the data

Abstract data type (ADT): a set of values, and the operations that can be performed on them.

Evolution of programming theory led to increased recognition of the value of both types of abstraction.

ADT: provides encapsulation for new data types: data plus functions

Data Abstraction

Page 4: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Encapsulation is a mechanism which allows logically related constants, types, variables, methods, and so on, to be grouped into a new entity.

Encapsulation mechanisms limit the scope and visibility of data and functions. Examples: functions, packages, classes.

Today, classes are the preferred mechanism Earlier mechanisms…

Encapsulation - Definition

Page 5: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

C: (13.2-13.3) Header file + implementation file

Modula 2: Modules – definition and implementation

Ada: (13.4-13.5) Package – definition and implementation◦ Later versions of Ada incorporate the idea of

classes – similar to C++ and Java.

Early Encapsulation Mechanisms

Page 6: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

A Stack Type in CFigure 13.2

stack.h is theheader file that specifies the STACK

data type.

Primitive ADT: Includes data and operations for an integer stack.

Page 7: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Implementation file has the functions:◦ empty, newstack, pop, push, top

Any program that includes the header can declare variables of type STACK and use the functions in the implementation file

Figure 13.3 – Implementation

Page 8: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

But…◦ There’s no way to prevent the client from

bypassing the defined stack operations to directly access a stack variable; e.g. to search the stack for a particular value

◦ There’s no way to generalize to other data types In other words ..

◦ no encapsulation, no inheritance Better: force stack access to be only

through the interface (defined stack functions).

Independent Compilation ≠ADT

Page 9: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Provide a public interface to the ADT through its operations (functions) and prevent any other access; but

Prevent public access to the underlying ADT representation

This is information hiding ◦ package data and functions in a unit that

provides access only through the defined interface.

Objectives of Data Abstraction

Page 10: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

One purpose of information hiding is to protect the rest of the program from implementation changes.

Implementation may change (e.g., to use an array instead of linked list) but interface doesn’t change◦ Stable interface means that applications that use the

ADT don’t need to change if the implementation of the ADT changes.

Information hiding also simplifies the programmer’s job – no need to understand details; use what you are given.

Purpose

Page 11: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

In contrast to the C example, Pascal “units”, Modula “modules” and Ada “packages” support information hiding.

Developers can prevent direct access to the underlying representation

Encapsulation - but lack other desirable characteristics.

Information Hiding Mechanisms

Page 12: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Figures 13.4 & 13.5 contain the Ada specification for a generic stack.

Ada packages are similar to C++/Java class definitions

Two parts: package definition & package implementation.

Data and functions can be public or private.

Ada Packages – page 313

Page 13: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Package stack_pck definition (13.4, p. 313):◦ Data + function declarations◦ Private and public (default) specification

Package implementation (13.4, p 314)◦ Function implementations

Package stack_pck is generic◦ Generic functions don’t specify a data type until

compilation time (similar to templates)

Ada Packages

Page 14: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Figure 13.4Generic Stack Specification in Ada

generic type element is private;package stack_pck is type stack is private; procedure … function … …

private type node; …

end stack_pckTo use in a program, instantiate with:package int_stack is new stack_pck(element=>integer);

Page 15: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

No mechanism for automatic initialization or for finalizing; e.g. file open/close, memory allocation, memory initialization, etc.

No simple way to extend ADT by adding new operations, modifying data characteristics, etc. (No inheritance)

Some computing paradigms were not well modeled by the imperative style.◦ But they could be modeled as a collection of objects that

communicate by sending messages to each other◦ e.g. GUI-based

Problems with Modules, Packages, etc.

Page 16: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Imperative: Design approach is functional decomposition + limited-feature abstract data types.

Object oriented: Design approach is object decomposition. Objects include both functions and data.

OO v Imperative Paradigm

Page 17: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

OO concepts are not new – Simula, an early (mid to late 60’s) OO

language, was developed as a simulation language◦ Included features for modeling the objects that

participated in the simulations Smalltalk (early 80’s) was the first language

to call itself object-oriented, but concepts came from Simula.

OO Programming/History

Page 18: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Class: A mechanism for defining a new type which encapsulates constants, variables, and functions for manipulating these variables.◦ Programmers can then declare new objects from the

defined type and operate on the objects with the class functions (methods).

OO languages fully support encapsulation and information hiding

Classes

Page 19: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

A language that allows multiple instances of an ADT to be created is said to be object-based.

An object-oriented language also supports inheritance and polymorphism (more about this later.

Object Based or Object Oriented?

Page 20: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Object: an instance (variable) of the class Instance variables: the local variables of a class.

Also called member variables, fields, … Methods: functions that operate on objects Local variables: variables declared in a method Message: a request to perform an operation on

an object (function call). Client (of a class): a program or class or method

that uses an object of the class data type

Section 13.2: The Object-Oriented Model

Page 21: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Inheritance◦ Allows classes to be modified and specialized,

which improves reusability. Constructors – a class method

◦ Special methods that allocate storage for an object & initialize its local instance variables

Destructors◦ Some languages have these to finalize objects

when they are no longer needed; e.g. free memory when an object’s scope ends.

OO Languages Address Problems That Exist in Modules & Packages

Page 22: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Program Organization Visibility and Information Hiding Methods and Constructors Inheritance Polymorphism

Features of OO Languages

Page 23: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

An object-oriented program is modeled as a collection of objects that communicate with each other by sending and receiving messages.

Classic example: GUI application◦ Objects = buttons, text areas, pull-down menus,

etc.

OO Program Organization

Page 24: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Class Definition - Java Class Definition – C++

public class C {private int i, j: //instance variables

public C (<params>){<code>}

// a constructor

public <type> M (<params>)

{<code>} // a method

} //end class C

class C {private: int i,j://instance variables

public: C::C (<params>)

{<code>} // a constructor

<type> C::M (<params>)

{<code>} // a method

} //end class C

Page 25: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Declare a variable as an object from the class C: (declaration)

C x; // No storage is allocated.or..

Declare & initialize a variable x that is an object from class C: (definition)

C x = new C(<arguments>); A new object is allocated on the heap

and assigned values.

Object Declaration and Initialization (Java syntax)

Page 26: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Initialization of an Object in the HeapFigure 7.6

Object is stored on the heap, pointer/reference to the object is stored on the stack, usually.

Page 27: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Objects are active, as opposed to the traditional view of data structures as entities that are acted on by functions.

A message is similar to a function call, but instead of being made by one function to another, a message is sent from one object to another.

Objects v. Data Structures

Page 28: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Visibility characterizes the degree of information hiding attached to components (methods, instance variables) of a class.

Visibility modifiers include◦ Private: visible only to the current class. ◦ Protected: visible also to a class’s subclasses &,

in Java, to members of other classes in the same package (an unfortunate design decision, according to the authors)

◦ Public: visible to any client or subclass of the class

Visibility in OO Languages

Page 29: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Friend functions in C++ can access private members of other classes.◦ Declared by the class granting access◦ Not a member of the class it friends; may be

part of another class Usually: class data is private (information

hiding) and methods public ◦forces clients to interface with the class

through its API (interface).◦Friend functions are a way to get around

this in special cases.

Visibility in OO Languages

Page 30: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

public class MyStack{ protected class Node {

public Object val;public Node next;public Node (Object v, Node n){

val = v; next = n;}

}private Node theStack;public MyStack ( ) {theStack = null;}public boolean empty ( ) { return theStack == null;}

public Object top( ) { return theStack.val; }public Object pop( ) {

Object result = theStack.val;theStack = theStack.next:return result;

}public void push(Object v) {

theStack = new Node(v, theStack);}

}

Figure 13.8 Stack Class with Visibility Modifiers

Note the inclusion of an inner class (not the same as a subclass)

The MyStack class is public, the Node class is protected (visible only to subclasses.) Stack data is private, the interface is defined by the functions empty, top, etc.

Page 31: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Note constructors in myStack example. Constructors are invoked by the new

operation; heap space is allocated and instance variables may be intialized ◦Node objects are initialized to values,◦MyStack objects are initialized to the null pointer

Constructors are examples of class methods.◦ Not invoked through a specific object

push, pop, etc. are examples of instance methods and are invoked through an object.

Constructors & Other Methods

Page 32: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Declare a myStack object as follows: myStack s = new myStack();

Create a stack with the values 1 and 5:s.push(1);s.push(2); s.pop(); // creates garbages.push(5);

Using the Stack

Page 33: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Creation of a Stack with Two ValuesFigure 13.7

Page 34: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Parent or superclass, child or subclass is-a relation: a member of a subclass is-a

member of the superclass has-a relation: if class A is a client of

class B, then A has-a B (has-a doesn’t reflect a subclass-superclass relationship)

Inheritance: The Class Hierarchy

Page 35: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

If D is a subclass of C, then D can acquire attributes (instance variables and methods, including constructors) from C.

In this case we may refer to C as the base class and D as the derived class or we say D extends C

Inheritance supports code reuse

Inheritance

Page 36: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

One or multiple superclasses Single inheritance produces a class

hierarchy that can be represented as a tree, with a single root. (Object, in Java)

Multiple inheritance class hierarchy is more like a graph – no unique parent node (e.g. C++)

Single v Multiple Inheritance

Page 37: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Inheritance from more that one parent has good features and bad.◦ Good: facilitates code reuse by borrowing

characteristics from several parent classes◦ Bad: confusing. For example, what if two parent

classes have a method with the same name, but different definitions?

Multiple Inheritance

Page 38: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Imperative languages are based on procedural abstraction and incorporate rudimentary data abstraction (e.g., modules and packages)

Object-oriented languages are based on the class concept, which lacks the weaknesses of earlier ADTs◦ Limited extensibility (inheritance), techniques for initializing

data (constructors), information hiding (encapsulation), etc. The design process in imperative languages is

based on functional decomposition; in OO languages design is based on decomposition into classes.

Review

Page 39: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

A language is object-oriented if it supports (1) an encapsulation mechanism with information hiding for defining abstract data types; e.g., classes (2) virtual methods, and (3) inheritance.

A language is object-based if it allows a program to create any number of instances of an abstract data type.

You may also see the 3 characteristics listed as (1) classes, (2) polymorphism, and (3) inheritance.

Definition of OO Programming

Page 40: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Informally, a class method is virtual if its subclasses (inheriting classes) can override the implementation in the original class.

Virtual methods allow OO languages to express polymorphism: the late binding of a call to one of several different implementations in an inheritance hierarchy. Often called runtime polymorphism

Compare to parametric polymorphism →

Virtual Methods & Polymorphism

Page 41: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Compare to parametric polymorphism: a function is defined as a template or generic.◦ Apply the same operations, in the same way, to

different data types In runtime polymorphism, virtual

(polymorphic) functions can also be applied to variables of different data types, and the functions themselves may behave differently.

Function or operator overloading is sometimes called ad hoc polymorphism.

Kinds of Polymorphism

Page 42: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Parametric polymorphism: a function is defined as a template or generic.

A template (also called generics) defines a family of classes parameterized by one or more types

Example: collection classes such as lists, stacks, queues, hash tables.◦ You can define a list of integers, list of nodes, etc.

Function code is written without any reference to types.◦ The functions are the same, regardless of the data type

they are applied to.

Parametric Polymorphism: Templates

Page 43: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

A polymorphic function is one that can be overridden in a subclass by a function that has the same signature.

Polymorphic functions have different implementations, depending on the subclass, but all have the same general purpose.

In a way, polymorphism is a form of information hiding – makes it possible to specify a general kind of behavior, and worry about details later (when subclasses are defined)

• This kind of polymorphism is sometimes called dynamic binding because the compiler may not be able to determine the type of an object until runtime, so can’t bind it to the right function. Ex: passing objects as parameters.

Runtime Polymorphism

Page 44: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Example: Class Hierarchy

Drawable

Triangle Square Ellipse Circle

paint()

The class “Drawable” has several subclasses, each of which has its own version of the paint function. A list (myList) of drawable objects is maintained. To draw each object: for(Drawable obj : myList) // uses the appropriate paint method

obj.paint();

Page 45: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

A subclass method is said to be substitutable for a parent class method because the subclass’s method performs the same general function◦ E.g. “paint” – but note that it is the same function

only in an abstract sense. This is the essence of polymorphism in OO

languages.

Principle of Substitutability

Page 46: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Abstraction is an essential feature of computer science. It is a way of filtering out specific details in order to focus on a few important concepts.

In OO programming, abstract classes support this design mechanism.

Abstract Classes

Page 47: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

An abstract class is one that is either declared to be abstract or has one or more abstract methods.

An abstract method is a method that contains no code beyond its signature.◦ signature = prototype

It’s not possible to instantiate an object from an abstract class, but it can be sub-classed.

Abstract Class

Page 48: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

/** * Java abstract class example * Abstract class represents skeleton of the classes which will extend this abstract class */

/**     * Vehicle abstract class is a general class of all vehicles     * It contains methods and attributes common to all vehicles     * but you can't create an instance of the Vehicle class     * Vehicle class is used as a basic structure for all specific vehicles (car,bus...)       */    abstract class Vehicle {        //subclasses will inherit an attribute        int maxSpeed;        //subclasses must implement this method         //(otherwise they have to be declared as abstract classes)        abstract void showMaxSpeed();         //subclass will have this method (through inheritance) as is (default implementation)        //or they may implement their own implementation (override a method)        int getWheelsNumber() {           return 4;        }

Example of an abstract classhttp://www.javacodeexamples.com/abstract-class/

Page 49: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

An abstract class can represent an abstract concept.Example:Clite Expression

Abstract syntax rule:Expression = VariableRef | Value | Binary | Unary

A Java implementation includes an abstract class Expression with subclasses VariableRef, Binary, Unary, Value.

An Abstract Class

Page 50: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Fig. 13 Clite Expression as an Abstract Class

Expression(abstract) display

Variable display

Value Binarydisplay

Unarydisplay

IntValuedisplay

FloatValuedisplay

BoolValuedisplay

CharValuedisplay

Page 51: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

Encapsulate a collection of constants and abstract method signatures. An interface may not include either variables, or constructors, or nonabstract methods.

Declared like an abstract class, except with the word interface. ( public interface Map {…} )

All methods in an interface are abstract & must be implemented by any class that implements the interface.

Java Interfaces

Page 52: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

A class may implement multiple interfaces, which allows it to appear to be many different types.

Similar to multiple inheritance A class can inherit from its parent, but also

draw features from interfaces.◦ No danger of conflicting method definitions if the

parent and interface have same-named methods; the inheriting class is required to re-implement the method

Java Interfaces

Page 53: Chapter 13.  Imperative program design is based on procedural abstraction and functional decomposition ◦ Procedural abstraction: supports reusable code.

OO languages ◦ support encapsulation and data abstraction

through the class mechanism◦ Provide constructors & sometimes destructors.

Characterized by inheritance and sub-type (runtime) polymorphism

Support run-time type identification (RTTI) which allows an object’s type to be identified at run time

Summary