Towards Object Oriented Computing
Lectures 9-11
- If ADT is so powerful then why do we need object oriented concepts ? What is that we cannot achieve using ADT ?
- Before answering it we look at software design and development. Given a scenario there are 2 ways to start the development :
- Function based : Here we identify functionality of the software
- Object based: Here we identify objects and their abstraction.
- We are given a container with geometric shape objects like Circle, Square, Triangle, Rectangle, . . . and operations that can be performed on them like : draw(), rotate(), . .
enum kind {circle, square, triangle, ...} //enumeration
Shape {
kind S_type; // type field for appropriate operations
Point Centre;
. . .
. . .
// . . . Constructor etc.
// . . . Operations : abstraction for all types of shapes
void draw ();
void rotate(int angle);
// ... Others
}
void draw(){ //pseudo-code
switch(S_type){
case circle:
draw_Circle(); break;
case square:
draw_Square(); break;
case triangle:
draw_Triangle(); break;
case default: break;
} }
- What are the issues with the above implementation ?
- To add a new shape type we need to examine every operation for Shape and modify it .e.g modify draw () method by adding another case.
We need access to the complete source code and there is possibility of bug introduction while touching the sources.
- How to extend the code without touching the sources ?
- Object oriented computing main crux is to maintain the code without touching the code to facilitate better reusability.
- To maintain the code we need to get rid of “kind” field which is programmable as it is used in switch statement. Object oriented computing works on non programmable type field i.e. type which code will not use, so that we can add any number of shapes. There are 3 possibilities
- Make everything void
- Typeless systems (but object oriented computing is not typeless)
- auto
None of the above are correct way.
- Requirements for maintainability are:
- Container may contain different sub-types like circle, triangle, square etc.
- For each subtype appropriate methods like draw,rotate etc. should be invoked without specifying that subtype.
- OOC: Inheritance and Polymorphism
- For each of the shape’s sub-type a single interface “draw/rotate” method should be used. therefore we need Inheritance.
- For each of the shape’s sub-type an appropriate “draw/rotate” method should be used. therefore we need Polymorphism.
- Basis of OOC is inheritance and basis of inheritance is commonality in relationships which can be between
- Type and subtype
- Class and subclass
- Superclass and class
- e.g. (Mammals:Man and Animal) where all have brain,hair, move with limbs, warm blooded etc. in common.
- Similarly (Parents:siblings) and (Shape:Circle,Square)
- Data type is implemented as Structure and Behaviour, so for inheritance there should be either structural commonality or behavioural commonality between the type and the subtypes.
- Polymorphism due to overloading: Multiple functions with same names but different types. We know at compile time which function will execute.
- Polymorphism due to overriding : Multiple functions with same name and same types. We do not know which function will execute before runtime.
- Overriding is independent of the programmable type field as opposite to overloading which is tied to the type field
- Anything in which decision has to be made at runtime is object oriented concept. It gives rise to static and dynamic types.
- Some mechanism is required to call the appropriate function depending on the subtype of the object. Therefore we have dynamic type where type is known at runtime. e.g. for vec[i].draw() static type of vec[i] is Shape while subtype is its dynamic type.
- One need not know the dynamic type to invoke appropriate method. Today’s object oriented languages can tell the dynamic type but previous languages could not tell but still both have mechanism to invoke appropriate method.
- Dynamic type is not a programmable field as opposed to static which is programmable.
- Abstraction
- Encapsulation
- Genericity (optional)
- Inheritance (this is must for OOC)
- Polymorphism due to overriding (this may be used)
- Types : Static and Dynamic
- Message Dispatch guided run-time binding
- Message Dispatch : It is equivalent to function invocation
- C language: It has Static linking or early binding. It gives pointer or address of where the function code is present. Decision is taken before the runtime which code to execute. It is called function call.
- OO language: It has runtime binding or late binding. Decision of which function to execute depends on the dynamic type and hence not known before runtime.It is called message dispatch.
- Semantics of function call : While writing the call statement we know which function to call.
- Semantics of message dispatch : consider call statement vec[i].draw()
- Name of method is called message i.e. draw()
- Object is called the receiver i.e. vec[i]
- Message is dispatched to receiver. It is responsibility of receiver to invoke appropriate method of message depending on the its runtime type.
- Nowhere programmer needs to know the dynamic type.
- The kind or sub-type field used here is dynamic type and hence not programmable. Non programmable attributes are called meta-data.
- Depending on the sub-type it invokes appropriate draw method. Thus OOC allows safe and trusted computing.
- What agencies are involved behind the magical behaviour
- Designer and coder - NO
- OOPL syntax - NO
- OOPL semantics - YES
- OOPLI or OO compiler carries out the OOPL semantics. It compiles the code is such a way that appropriate decisions could be taken at run-time.
- Inheritance Implementation
- Basis of OOC maintainability is Inheritance and that of Inheritance is commonality. Therefore first step is to identify the commonality between and class and the subclass.
e.g.
| Structural (Y/N/P/X) | Behavior (Y/N/P/X) |
Mammals : Man, Animal | Y | X |
Parents : Sibling | Y | X |
Shape:Circle, Square . . | N | Y |
int angle;
vector <shape> vec; // pseudo-code
for(i=0; i<vec.size; i++) vec[i].draw();
for(i=0; i<vec.size; i++)vec[i].rotate(angle);
In the above code, behaviour or abstraction of the shapes, is reused for extendibility. The structural property do not participate much in maintainability of the code. Common structural property make the implementation easier. Anyways the implementation details specific to the structure and encapsulated.
- Thus start point for designing a Software i.e. basis of Inheritance is commonality of abstraction.
- Scenario1 : Shape Software
- Description: A container contains several shapes, which are defined as,
- Circle: centre and radii
- Triangle: base, height, angle, or
- Square: side and LB point
- Rectangle: Base, LB point, and other side
- ….
- The Software should be able to draw above geometric shaped objects on a display supported by graphic (pixel, line …) utilities. Shapes could be rotated and intersected.
- 2 approaches for designing the solution are:
- Data Structure approach: Make type-definitions using union constructs.
- Identify entities or objects like Container, Geometric Shaped Objects & Graphics and group them based on behavior. this approach leads to a maintainable software.
- Scenario2 : Object oriented analysis and design
- Design and Develop a Zoo Management Software System that has
- mammals, who are caged.
- administrative units, who take care of these animals for feeding, servicing..
- visitors, like general public, animal rights activists, media persons, advt./movie-makers etc.
- 2 approaches for designing the solution are:
- Data Structure approach: Make type-definitions using union constructs.
Make a hierarchy of
- : Mammals (Super Class): Animals, Persons
- : Persons : Administrators (sub-classes) & Visitor (sub-classes)
- Identify entities or objects and group them based on behavior.
- Software that is build on this Zoo is based on the behavior eventhough all the three unit have same structure.So that means by just giving entities we can not make system.
- We can see that second approach leads to more superior and maintainable software.
Thus from both the scenarios we can conclude that start point of software design is commonality of abstraction.
- OOC : Separation of Interface & Implementation
- We analysed this point with respect to ADT computing but it is more relevant to OO analysis and design.
- For a better maintainable Software we first, analyse the Interface, and then Implement it.
- First look at the abstraction
- Then depending on the commonalities of abstraction decide where can we use inheritance
- Then override the common behaviour using class subclass relationship.
- Type safety in OOC : Trusted & Safer
- Trusted Computing because
- Subtype is a non-programmable attribute.
- Behavior is preserved.
- Safe Type due to Restricted Typecasting
- Type-casting permitted within the objects of the hierarchy, in vertical.
- Implicit : Super Class Ref. <- Sub Class Object/Ref. It is also called Type Substitution
- Explicit : Sub Class Ref. <- Super Class .It is also called as Dynamic Casting, It is permitted at runtime, if dynamic cast is matched
- No Casting amongst siblings.
- Example: consider a class hierarchy:
- Animal (Super Class): Man and Monkey (sub-classes)
- Behavior: Eat, Walk, Climb (common behavior)
Animal oA; // Animal Ref.
Man oMan = new Man();
Monkey oMnk = new Monkey();
oA = oMan; // Type substitution
oA.climb(); // Static: climb like Animal
// Dynamic: climb like Man
oA = oMnk; // Type substitution
oA.climb(); // Static: climb like Animal
// Dynamic: climb like Monkey
oMnk = (Monkey) oA; // Dynamic Cast : YES
oMan = (Man) oA; // Dynamic Cast : Exception @ runtime
oMan = (Monkey) oA; // Compilation Err’
// No type casting amongst siblings
- Object Oriented Computing helps code maintainable for extendibility.
- OO Computing includes:
- Inheritance (must)
- Polymorphism by overriding (optional)
- Message Dispatch
- Static and Dynamic Types
- Basis of OOC is Inheritance and basis of Inheritance is commonality of abstraction.
- Separation of interface & implementation for reusability.
- Trusted & Safe type due to restricted typecasting.
- Compiler supports OOPL semantics to take decisions at runtime.