Why OOPs: Object oriented programming enables programmers define not only the data, but also its associated behaviors/functions that can be applied to the data. It also enables programmers to create relationships between one object and another. For example, objects can inherit characteristics from other objects.
To understand the importance of OOP we need to first understand the problem with procedural/structural programming practices. Procedural programming was suitable for small projects. But as the program grew in size, along with it grew the maintenance nightmare. Also, since the modules were tightly integrated changes in one part of the module inadvertently breaks the other part. Team development was not truly achievable. The next big problem with procedural programming was with respect to reusability. It was very difficult to write truly reusable code, with minimum maintenance.
So why OOP? OOPs facilitates code reuse, team-development, eliminate redundant code, easy management of software complexity etc. To understand how OOP practices enable us to write better, maintainable software, we need to understand some of the fundamental aspects of OOP.
Fundamentals of OOPS
To understand the fundamentals of OOPS, we need to be familiar with some of the terms programmers frequently use while developing object oriented software.
Classes and Objects: The class represents or defines the common characteristics/attributes of an object of a particular type. For e.g. you might want to define a class of “Person”. Every person will share some common characteristics/attributes like first name, last name, address etc.. So, a class serves as a blueprint for similar type of object. A class is made up of attributes and behavior. Attributes are defined in terms of member variables and behavior is expressed in terms of function.
An object is an instance of a class. It is a representation of a real world thing. Object can have both attributes/data and behaviors. For e.g. you, me are instance of the “Person” class. We share some common attributes like we both have a first name, a last name and soon. We have some common behaviors like walking, talking etc.
Abstraction: Abstraction refers to the act of representing essential features without unnecessarily including the background details or information i.e. representing a complex problem in simple terms. Classes provides a mechanism to abstract the required attributes such as first name, last name in case of “Person” class and functions to operate on these attributes. Classes are also known as “Abstract Data Type or ADT”.
Encapsulation (or Information Hiding): Encapsulation is a technique where data and its associated behaviors (function) are wrapped in a single unit (Class). The data is hidden from the outside word. The purpose is to reveal as little as possible about the inner workings of the class. The only way to access these data is through public interfaces provided by the functions.
Inheritance is a technique with which an object of one class acquires attributes and behaviors from an object of another class. This is one way to achieve reusability in OOP.
Inheritance models “is-a” relationship. For e.g. a “car” is an automobile. In this case the “automobile” is called the base class and “car” is called as derived class or inherited class. This type of reuse is often called white-box reuse. This term refers to the fact that with inheritance, the parent class implementation is often visible to the subclasses.
Below is how practically encapsulation and inheritance is implemented in C#. The “:” says that clsJobSeeker is the child of clsUser class and that’s how we define inheritance in C#. The private key shows how the complication is hidden from the external world.
public class clsJobSeeker : clsUser
private string _JobSeekerName;
private string _SurName;
private string _Address;
private string _PhoneNumber;
Composition: When reuse is achieved by composing another object, the technique is known as composition. Composition models “has-a” relationship. This approach requires that the objects have well-defined interfaces since the internals of the objects are unknown. Because objects are treated only as “black boxes,” this type of reuse is often called blackbox reuse below is the code snippet which shows how composition is implemented in C#. In the below scenario clsUser is composed of clsMenus objects. So we create clsMenus object inside the clsUser class.
public class clsUser
private clsMenus objMenus = new clsMenus();
Polymorphism: The ability of different objects to respond to the same message in different ways is called polymorphism. Polymorphism is also the ability of an object to take more than one forms, for e.g. an operation may exhibit different behavior in different instances. The behavior depends upon the types of data used in the operation. There are basically two types of polymorphism i.e. static and dynamic polymorphism. Method overloading is an example of static polymorphism whereas overriding would be an example of dynamic polymorphism. Below is how we implement polymorphism in project practically. There are two methods Login and Login with userId. So if the external consumer who is using this component calls only the login method it loads the entire user and if they pass the userid then it will load only that user details.
public void login()
public void login(int intUserId)
Message: An object in isolation is of no use. Its value comes from its interactions with other objects. This interaction takes place through messages. A message consists of three parts
- A receiver object
- A method the receiver knows how to execute
- Parameters, if any.
Cohesion: Cohesion is a measure of how much an item, say for e.g. a class or method, makes sense. Objects with low cohesion are more likely to be changed. A method is highly cohesive if it does one thing and only one thing. High cohesion is desirable.
Coupling: Object coupling describes the degree of interrelationships among the objects that make up a system. The more anyone object knows about any other object in the system, the tighter the coupling is between those objects. In other words, coupling is a measure of how two items, such as classes or methods, are interrelated. When one class depends on another class they are said to be coupled. When one class interacts with another class, but does not have any knowledge of the implementation details of the other class they are said to be loosely coupled. When one class relies on the implementation of another class, they are said to be tightly coupled. Always try for loose coupling among objects.