UNIT 1
Foundations of Object Oriented Programming
- Give a brief Introduction OOP: Software Evolution
Answer: Ernest Tello, A well-known writer in the field of artificial intelligence, compared the evolution of software technology to the growth of the tree. Like a tree, the software evolution has had distinct phases “layers” of growth. These layers were building up one by one over the last five decades as shown with each layer representing and improvement over the previous one. However, the analogy fails if we consider the life of these layers. In software system each of the layers continues to be functional, whereas in the case of trees, only the uppermost layer is functional
Alan Kay, one of the promoters of the object-oriented paradigm and the principal designer of Smalltalk, has said: “As complexity increases, architecture dominates the basic materials”. To build today’s complex software it is just not enough to put together a sequence of programming statements and sets of procedures and modules; we need to incorporate sound construction techniques and program structures that are easy to comprehend implement and modify.
With the advent of languages such as c, structured programming became very popular and was the main technique of the 1980’s. Structured programming was a powerful tool that enabled programmers to write moderately complex programs fairly easily. However, as the programs grew larger, even the structured approach failed to show the desired result in terms of bug-free, easy-to- maintain, and reusable programs.
Object Oriented Programming (OOP) is an approach to program organization and development that attempts to eliminate some of the pitfalls of conventional programming methods by incorporating the best of structured programming features with several powerful new concepts. It is a new way of organizing and developing programs and has nothing to do with any particular language. However, not all languages are suitable to implement the OOP concepts easily.
2. Give a brief Introduction to Procedural
Answer: In the procedure oriented approach, the problem is viewed as the sequence of things to be done such as reading, calculating and printing such as cobol, fortran and c. The primary focus is on functions. A typical structure for procedural programming is shown. The technique of hierarchical decomposition has been used to specify the tasks to be completed for solving a problem.
Procedure oriented programming basically consists of writing a list of instructions for the computer to follow, and organizing these instructions into groups known as functions. We normally use flowcharts to organize these actions and represent the flow of control from one action to another.
In a multi-function program, many important data items are placed as global so that they may be accessed by all the functions. Each function may have its own local data. Global data are more vulnerable to an inadvertent change by a function. In a large program it is very difficult to identify what data is used by which function. In case we need to revise an external data structure, we also need to revise all functions that access the data. This provides an opportunity for bugs to creep in.
Another serious drawback with the procedural approach is that we do not model real world problems very well. This is because functions are action-oriented and do not really corresponding to the element of the problem.
Some Characteristics exhibited by procedure-oriented programming are: • Emphasis is on doing things (algorithms).
• Large programs are divided into smaller programs known as functions.
• Most of the functions share global data.
• Data move openly around the system from function to function.
• Functions transform data from one form to another.
• Employs top-down approach in program design.
3. Write the Principles of Object-Oriented Systems
Answer: The conceptual framework of object–oriented systems is based upon the object model. There are two categories of elements in an object-oriented system −
Major Elements−By major, it is meant that if a model does not have any one of these elements, it ceases to be object oriented. The four major elements are −
- Abstraction
- Encapsulation
- Modularity
- Hierarchy
Minor Elements−By minor, it is meant that these elements are useful, but not indispensable part of the object model. The three minor elements are −
- Typing
- Concurrency
- Persistence
Abstraction
Abstraction means to focus on the essential features of an element or object in OOP, ignoring its extraneous or accidental properties. The essential features are relative to the context in which the object is being used.
Grady Booch has defined abstraction as follows −
“An abstraction denotes the essential characteristics of an object that distinguish it from all other kinds of objects and thus provide crisply defined conceptual boundaries, relative to the perspective of the viewer.”
Example− When a class Student is designed, the attributes enrolment_number, name, course, and address are included while characteristics like pulse_rate and size_of_shoe are eliminated, since they are irrelevant in the perspective of the educational institution.
Encapsulation
Encapsulation is the process of binding both attributes and methods together within a class. Through encapsulation, the internal details of a class can be hidden from outside. The class has methods that provide user interfaces by which the services provided by the class may be used.
Modularity
Modularity is the process of decomposing a problem (program) into a set of modules so as to reduce the overall complexity of the problem. Booch has defined modularity as −
“Modularity is the property of a system that has been decomposed into a set of cohesive and loosely coupled modules.”
Modularity is intrinsically linked with encapsulation. Modularity can be visualized as a way of mapping encapsulated abstractions into real, physical modules having high cohesion within the modules and their inter–module interaction or coupling is low.
Hierarchy
In Grady Booch’s words, “Hierarchy is the ranking or ordering of abstraction”. Through hierarchy, a system can be made up of interrelated subsystems, which can have their own subsystems and so on until the smallest level components are reached. It uses the principle of “divide and conquer”. Hierarchy allows code reusability.
The two types of hierarchies in OOA are −
- “IS–A” hierarchy− It defines the hierarchical relationship in inheritance, whereby from a super-class, a number of subclasses may be derived which may again have subclasses and so on. For example, if we derive a class Rose from a class Flower, we can say that a rose “is–a” flower.
- “PART–OF” hierarchy− It defines the hierarchical relationship in aggregation by which a class may be composed of other classes. For example, a flower is composed of sepals, petals, stamens, and carpel. It can be said that a petal is a “part–of” flower.
Typing
According to the theories of abstract data type, a type is a characterization of a set of elements. In OOP, a class is visualized as a type having properties distinct from any other types. Typing is the enforcement of the notion that an object is an instance of a single class or type. It also enforces that objects of different types may not be generally interchanged; and can be interchanged only in a very restricted manner if absolutely required to do so.
The two types of typing are −
- Strong Typing− Here, the operation on an object is checked at the time of compilation, as in the programming language Eiffel.
- Weak Typing− Here, messages may be sent to any class. The operation is checked only at the time of execution, as in the programming language Smalltalk.
Concurrency
Concurrency in operating systems allows performing multiple tasks or processes simultaneously. When a single process exists in a system, it is said that there is a single thread of control. However, most systems have multiple threads, some active, some waiting for CPU, some suspended, and some terminated. Systems with multiple CPUs inherently permit concurrent threads of control; but systems running on a single CPU use appropriate algorithms to give equitable CPU time to the threads so as to enable concurrency.
In an object-oriented environment, there are active and inactive objects. The active objects have independent threads of control that can execute concurrently with threads of other objects. The active objects synchronize with one another as well as with purely sequential objects.
Persistence
An object occupies a memory space and exists for a particular period of time. In traditional programming, the lifespan of an object was typically the lifespan of the execution of the program that created it. In files or databases, the object lifespan is longer than the duration of the process creating the object. This property by which an object continues to exist even after its creator ceases to exist is known as persistence.
4. What are the Object-oriented programming techniques?
Answer: Object-oriented programming is based on the three concepts encapsulation, inheritance, and polymorphism.
Encapsulation
An object encapsulates its attributes and methods and provides them via an interface to the outside world. This property that an object hides its implementation is often called data hiding.
Inheritance
A derived class get all characteristics from its base class. You can use an instance of a derived class as an instance of its base class. We often speak about code reuse because the derived class automatically gets all characteristics of the base class .
Polymorphism
Polymorphism is the ability to present the same interface for differing underlying data types. The term is from Greek and stands for many forms.
1 2 3 4 5 6 7 8 9 10 11 12 13 | Class HumanBeing{ Public: HumanBeing(std::stringn):name(n){} virtual std::string getName() const{ return name; } Private: Std::string name; };
Class Man: public HumanBeing{};
Class Woman: public HumanBeing{}; |
In the example you only get the name of HumanBeing by using the method getName in line 4 (encapsulation). In addition, getName is declared as virtual. Therefore, derived classes can change the behaviour of their methods and therefore change the behaviour of their objects (polymorphism). Man and Woman are derived from HumanBeing.
5. What is Generic programming?
Answer: The key idea of generic programming or programming with templates is to define families of functions or classes. By providing the concrete type you get automatically a function or a class for this type. Generic programming provides similar abstraction like object-oriented programming. A big difference is that polymorphism of object-oriented programming will happen at runtime; that polymorphism of generic programming will happen in C++ at compile time. That the reason why polymorphism at runtime is often called dynamic polymorphism but polymorphism at compile is often called static polymorphism.
By using the function template I can exchange arbitrary objects.
1 2 3 4 5 6 7 8 9 10 11 12 | Template <typename T> void xchg(T& x, T& y){ T t= x; x= y; y= t; }; Inti= 10; Int j= 20; Man huber; Man maier;
Xchg(i,j); Xchg(huber,maier); |
It doesn't matter for the function template, if I exchange numbers or men (line 11 and 12). In addition, I have not to specify the type parameter (line) because the compiler can derived it from the function arguments (line 11 and 12).
The automatic type deduction of function templates will not hold for class templates. In the concrete case I have to specify the type parameter T and the non-type parameter N (line 1).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Template <typename T, int N> Class Array{ Public: IntgetSize() const{ return N; } Private: T elem[N]; };
Array<double,10>doubleArray; Std::cout<<doubleArray.getSize() <<std::endl;
Array<Man,5>manArray; Std::cout<<manArray.getSize() <<std::endl; |
Accordingly, the application of the class template Array is independent of the fact, whether I use doubles or men.
6. What is Functional programming?
Answer: A will only say a few words about functional programming because I will and can not explain the concept of functional programming in a short remark. Only that much. I use the code snippet the pendants in C++ to the typical functions in functional programming: map, filter, and reduce. These are the functions std::transform, std::remove_if, and std::accumulate.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Std::vector<int>vec{1,2,3,4,5,6,7,8,9}; Std::vector<std::string>str{"Programming","in","a","functional","style."};
Std::transform(vec.begin(),vec.end(),vec.begin(), [](inti){ return i*i; }); // {1,4,9,16,25,36,49,64,81}
Auto it= std::remove_if(vec.begin(),vec.end(), [](inti){ return ((i< 3) or (i> 8)) }); // {3,4,5,6,7,8} Auto it2= std::remove_if(str.begin(),str.end(), [](string s){ return (std::lower(s[0])); }); // "Programming"
Std::accumulate(vec.begin(),vec.end(),[](inta,int b){return a*b;}); // 362880 Std::accumulate(str.begin(),str.end(), [](std::string a,std::string b){return a + ":"+ b;}); // "Programming:in:a:functional:style." |
I apply in the code snippet two powerful features of functional programming. Both are now mainstream in modern C++: automatic type deduction with auto and lambda-functions.
7. What are the Limitations of Procedural Programming?
Answer: Well, although procedural-oriented programs are extremely powerful, they do have some limitations.
- Perhaps the most serious limitation is the tendency for large procedural-based programs to turn into "spaghetti-code".
- Spaghetti code is code that has been modified so many times that the logical flow shown in the figures above becomes so convoluted that any new programmer coming onto the project needs a two month prep-course in order to even begin to understand the software innards.
- Why does this happen?
- Well, in reality, a programmer's job has just begun when she finishes writing version 1.0 of her software application. Before she knows it, she'll be bombarded with dozens of modification requests and bug reports as users actually get to batter and bruise her poor piece of code.
- In order to meet the demands of the evil user, the programmer is forced to modify the code. This can mean introducing new sub loops, new eddies of flow control and new methods, libraries and variables altogether.
- Unfortunately, there are no great tools for abstraction and modularization in procedural languages...thus, it is hard to add new functionality or change the work flow without going back and modifying all other parts of the program.
- Now, instead of redesigning the workflow and starting from scratch, most programmers, under intense time restrictions will introduce hacks to fix the code.
- This gets us to the second problem with procedural-based programming. Not only does procedural code have a tendency to be difficult to understand, as it evolves, it becomes even harder to understand, and thus, harder to modify.
- Since everything is tied to everything else, nothing is independent. If you change one bit of code in a procedural-based program, it is likely that you will break three other pieces in some other section that might be stored in some remote library file you'd forgotten all about.
- A final problem with spaghetification is that the code you write today will not help you write the code you have to write tomorrow. Procedural-based code has a tenacious ability to resist being cut and pasted from one application to another. Thus, procedural programmers often find themselves reinventing the wheel on every new project.
8. Explain objects and classes
Answer: Objects
Objects are the basic run time entities in an object-oriented system. They may represent a person, a place, a bank account, a table of data or any item that the program has to handle. They may also represent user-defined data such as vectors, time and lists. Programming problem is analyzed in term of objects and the nature of communication between them. Program objects should be chosen such that they match closely with the real-world objects. Objects take up space in the memory and have an associated address like a record in Pascal, or a structure in c.
When a program is executed, the objects interact by sending messages to one another. For example, if “customer” and “account” are to object in a program, then the customer object may send a message to the count object requesting for the bank balance. Each object contain data, and code to manipulate data. Objects can interact without having to know details of each other’s data or code. It is a sufficient to know the type of message accepted, and the type of response returned by the objects. Although different author represent them differently shows two notations that are popularly used in object-oriented analysis and design.
Classes
We just mentioned that objects contain data, and code to manipulate that data. The entire set of data and code of an object can be made a user-defined data type with the help of class. In fact, objects are variables of the type class. Once a class has been defined, we can create any number of objects belonging to that class. Each object is associated with the data of type class with which they are created. A class is thus a collection of objects similar types. For examples, Mango, Apple and orange members of class fruit. Classes are user-defined that types and behave like the built-in types of a programming language. The syntax used to create an object is not different then the syntax used to create an integer object in C. If fruit has been defines as a class, then the statement
Fruit Mango;
Will create an object mango belonging to the class fruit.
9. Explain Data Members
"Data Member" and "Member Functions" are the new names/terms for the members of a class, which are introduced in C++ programming language.
The variables which are declared in any class by using any fundamental data types (like int, char, float etc) or derived data type (like class, structure, pointer etc.) are known as Data Members. And the functions which are declared either in private section of public section are known as Member functions.
There are two types of data members/member functions in C++:
- Private members
- Public members
1) Private members
The members which are declared in private section of the class (using private access modifier) are known as private members. Private members can also be accessible within the same class in which they are declared.
2) Public members
The members which are declared in public section of the class (using public access modifier) are known as public members. Public members can access within the class and outside of the class by using the object name of the class in which they are declared.
Consider the example:
Class Test
{
Private:
Int a;
Float b;
Char *name;
VoidgetA() { a=10; }
...;
Public:
Int count;
VoidgetB() { b=20; }
...;
};
Here, a, b, and name are the private data members and count is a public data member. While, getA() is a private member function and getB() is public member functions.
How to declare, define and access data members an member functions in a class?
#include <iostream>
#include <string.h>
Using namespace std;
#define MAX_CHAR 30
//class definition
Class person
{
//private data members
Private:
Char name [MAX_CHAR];
Int age;
//public member functions
Public:
//function to get name and age
Void get(char n[], int a)
{
Strcpy(name , n);
Age = a;
}
//function to print name and age
Void put()
{
Cout<< "Name: " << name <<endl;
Cout<< "Age: " <<age <<endl;
}
};
//main function
Int main()
{
//creating an object of person class
Person PER;
//calling member functions
PER.get("Manju Tomar", 23);
PER.put();
Return 0;
}
Output
Name: Manju Tomar
Age: 23
As we can see in the program, that private members are directly accessible within the member functions and member functions are accessible within in main() function (outside of the class) by using period (dot) operator like object_name.member_name;
Data Encapsulation
All C++ programs are composed of the following two fundamental elements −
- Program statements (code) − This is the part of a program that performs actions and they are called functions.
- Program data − The data is the information of the program which gets affected by the program functions.
Encapsulation is an Object Oriented Programming concept that binds together the data and functions that manipulate the data, and that keeps both safe from outside interference and misuse. Data encapsulation led to the important OOP concept of data hiding.
Data encapsulation is a mechanism of bundling the data, and the functions that use them and data abstraction is a mechanism of exposing only the interfaces and hiding the implementation details from the user.
C++ supports the properties of encapsulation and data hiding through the creation of user-defined types, called classes. We already have studied that a class can contain private, protected and public members. By default, all items defined in a class are private. For example −
Class Box {
Public:
DoublegetVolume(void) {
Return length * breadth * height;
}
Private:
Double length; // Length of a box
Double breadth; // Breadth of a box
Double height; // Height of a box
};
The variables length, breadth, and height are private. This means that they can be accessed only by other members of the Box class, and not by any other part of your program. This is one way encapsulation is achieved.
To make parts of a class public (i.e., accessible to other parts of your program), you must declare them after the public keyword. All variables or functions defined after the public specifier are accessible by all other functions in your program.
Making one class a friend of another exposes the implementation details and reduces encapsulation. The ideal is to keep as many of the details of each class hidden from all other classes as possible.
10. Explain Data Encapsulation with Example
Answer: Any C++ program where you implement a class with public and private members is an example of data encapsulation and data abstraction. Consider the following example −
#include <iostream>
Using namespace std;
Class Adder {
Public:
// constructor
Adder(inti = 0) {
Total = i;
}
// interface to outside world
VoidaddNum(int number) {
Total += number;
}
// interface to outside world
IntgetTotal() {
Return total;
};
Private:
// hidden data from outside world
Int total;
};
Int main() {
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
Cout<< "Total " <<a.getTotal() <<endl;
Return 0;
}
When the above code is compiled and executed, it produces the following result −
Total 60
Above class adds numbers together, and returns the sum. The public membersaddNum and getTotal are the interfaces to the outside world and a user needs to know them to use the class. The private member total is something that is hidden from the outside world, but is needed for the class to operate properly.
Designing Strategy
Most of us have learnt to make class members private by default unless we really need to expose them. That's just good encapsulation.
This is applied most frequently to data members, but it applies equally to all members, including virtual functions.