# Object-Oriented Programming Concepts

## Summary


Developers who are familiar with procedural languages such as C and Pascal will understand variables, functions, and scope. When learning an object-oriented programming (OOP) language such as Java or C++, the same developers might have difficulty. This article presents an overview of OOP concepts.

Whereas the building block of procedural languages is a **function** or procedure, the building block of OOP languages is an **object**. Procedural languages have variables (data) and functions (code). In OOP, objects contain both data and code. With procedural languages, functions operate on data. With OOP, objects operate on their own data and selectively expose this data to other objects. 

Different OOP languages sometimes differ in terminology. Some OOP languages may lack advanced OOP features. In general, OOP concepts are mostly similar across languages.

## Discussion

### What are objects and classes in OOP?

In the real world, just about anything can be seen as an object: car, dog, person, department, city, etc. These have **state** and **behaviour**. For example, a dog's state is its colour, breed and name; its behaviour is the way it barks, runs or wags its tail. Objects in OOP are quite similar. 

In OOP, an **object** is a software construct that includes both data and code to process that data. Unlike procedural languages in which functions are independent of variables, OOP objects retain control of their state and how others can affect that state via executable code. Data specifies the state of the object whereas executable code specifies behaviour. A real-world dog could be represented in OOP as a software object. 

Let's create many dogs of the same or different breeds. It's inefficient to write code for each dog. This is where the concept of **class** becomes important. A class is sort of a blueprint from which an object can be created. Thus, each dog is an *instance* of the same `Dog` class. **Instantiation** is the process of creating objects or instances from classes. 


### What are attributes and methods of objects in OOP?

Attributes contain an object's state. Methods define an object's behaviour. Both are bound to the object and therefore accessed via the object. Attributes are also called properties, fields or instance variables. Each object has its own copy of attributes in memory. As for methods, only their addresses are stored within an object. Attributes and methods are also called **members**. 

Consider the class `Rectangle`. It's attributes could be `length` and `breadth`. It's methods could be `getArea()` and `rotate()`. 

Two special methods are worth noting: constructor and destructor. When an object is instantiated from its class, the **constructor** method is called to initialize the object state. When the object is destroyed, its **destructor** method is called so that necessary clean up is done. 

Consider a database connector class. The constructor method might initialize the database server IP address, port, username and password for access. It might even open the DB connection. The destructor on the other hand might abort pending queries and close the connection. Other methods of the class might manage the connection, process DB queries and responses. 


### Which are the essential concepts of OOP?

Among the many concepts of OOP, three stand out: 

    + **Encapsulation**: A class and its instances bring together attributes and methods that are closely related. Encapsulation hides internal implementation and exposes public interfaces. Thus, it achieves *data hiding*.
    + **Inheritance**: Using an existing class, a more refined class can be created. The former is called a *base class* or *super class*. The latter is called a *derived class* or *subclass*. For example, `Shape` is a base class from which `Square` and `Circle` are derived classes. Base class might define common attributes such as colour and line width. Derived classes might define more specific attributes such as length or radius, and specific methods to compute area and perimeter.
    + **Polymorphism**: Different classes having the same attributes and methods, though implemented differently, can be interchanged at runtime. For example, a `Canvas` object might wish to compute the area of a shape object. It doesn't care if it's a square or a circle since both have the `getArea()` method. Canvas object calls this method on a shape object and the correct method of the current derived object is called.

### What is meant by abstraction in OOP?

Abstraction is about describing something at a conceptual level while leaving out the details. For example, we may talk about a vehicle without being explicit if it's a ship or a car. Abstraction a useful design tool since considering too many details upfront can be distracting and confusing. We start with an abstract concept and refine it later by adding more details to it. It's been said that, 

> Abstraction hides details at the design level, while encapsulation hides details at the implementation level.

Consider `Shape` class with members `color` and `getArea()`. Subclasses `Rectangle` and `Triangle` implement how area is calculated. Since `Shape` doesn't know how to calculate area, we call it an **abstract class**. It can't be instantiated. Only its subclasses that provide an implementation of `getArea()` can be instantiated. Shape's `getArea()` is an **abstract method**. 

Other than inheritance, an alternative to achieve abstraction is to use interfaces. **Interfaces** provide method signatures without implementing them. Classes that adopt these interfaces are required to implement them. **Mixins** are similar to interfaces except that they implement the methods themselves. 


### How is composition different from inheritance in OOP?

Consider the classes `Vehicle`, `Car` and `Engine`. Car is a *type of* vehicle whereas engine is *part of* a car. The relationship between vehicle and car is best modelled as **inheritance**: `Car` is a subclass of `Vehicle`. The relationship between engine and car is best modelled as **composition**: an `Engine` instance is an attribute of either `Vehicle` or `Car` class. 

While both inheritance and composition are relevant to OOP, it's important for software architects and designers to look at the relationships among classes to select the right one. Specifically, we should ask, "Is it a *is-a* or a *has-a* relation?" Inheritance is a pillar of OOP but composition is essential to every language. 

Two other concepts closely related to composition are **association** and **aggregation**. Aggregation describes a *part-whole* relation. A `Course` object is part of a `DegreeProgram` object. It's also a many-to-many relation since the same course can belong to different programs and a program has many courses. 

Some languages such as JavaScript, allow **prototypal inheritance**. Object prototypes form the basis of other objects. Classes don't exist.  


### What are access modifiers in the context of OOP?

It's possible to restrict access to classes, methods and attributes. By the *principle of least privilege*, limit access only to classes that need it. 

In Java, when no access modifier is specified, all classes within the package get access. Otherwise, we can use the following access modifiers:  

    + `public`: Access is allowed for all classes.
    + `protected`: Access is allowed for subclasses (in any package) and classes within the same package. Thus, access is allowed only to closely related classes.
    + `private`: Access is allowed only within the class to which the members belong. This is typically used to hide data within the class. Any access to private data is provided via methods. Read and write access are via **getters** and **setters** respectively. These are also called **accessors** and **mutators**.In Kotlin, the term *visibility modifier* is used. Modifier `internal` gives access to all classes within the same module. Modifier `protected` gives access to subclasses. 

In C++, access modifiers can also be applied to inheritance. For example, private inheritance would make all methods and attributes of the base class private and therefore inaccessible to the subclass. 


### What are static classes and methods?

We know that objects are at the centre of OOP. However, there are use cases that don't need to store state. Class methods operate only on the input arguments they receive. In this case, we use a **static class**. In .NET, `System.Math` is an example of a static class. 

A static class contains only static members. It can't be instantiated into objects. It's accessed by its class name, and not by instance variable name as is customary with objects. 

Sometimes we wish to share an attribute across all objects of a class. For example, `numberOfBicycles` is an attribute that should be shared across all `Bicycle` objects. Java's `static` modifier can be used to make this a **static variable**. Likewise, a method to access this static attribute is called a **static method**. Static methods can access only static members. The class itself need not be static. 


### What are some additional concepts in OOP?

Some OOP concepts are not common to all languages or were introduced later as languages evolved. We mention a few of these:

    + **Multiple Inheritance**: This is when a subclass inherits from multiple base classes. C++ and Python support this. In Java and C#, a class can implement multiple interfaces but not inherit from multiple classes.
    + **Generics**: Classes, methods and interfaces that can be parameterized are called generics. For example, a class might implement a set of objects with parameterized type. Thus, the same class definition can be used to instantiate a set of `Shape` objects or `Car` objects.
    + **Templates**: Whereas types in generics are substituted at runtime, types in templates are specialized at compile time. Each template specialization has its own compiled code. C++ and D support templates.
    + **Delegates**: We can call a method via its delegate that has a compatible method signature. With delegates, methods can be passed as arguments to other methods.
    + **Reflection**: Not exclusive to OOP, reflection allows a class to introspect and modify its own definition. In Java, reflection is possible on classes, interfaces, fields and methods at runtime. This is often useful for testing, data serialization and metaprogramming.


## Milestones

1967

**Simula 67** is born, officially the first object-oriented programming language. It's initially used in computer simulations. Classes in this language are called *processes* since object lifecycle depends on the process executing the statements. 

1985

In the mid-1980s, many systems and application programmers adopt C++ for OOP. It takes another decade (1990s) for OOP to become more widely adopted. 

Oct  
1994

Object-oriented programming (OOP) and object-oriented design (OOD) are quite complex. To give software architects and developers guidelines to get these right, principles and design patterns have evolved over the years. At ACM's annual OOPSLA conference, four authors announce their book titled *Design Patterns: Elements of Reusable Object-Oriented Software*. This book describes 23 **software design patterns**. In time, this book becomes an essential read for OOP and OOD. 

Dec  
1997

Object Management Group (OMG) standardizes **Unified Modelling Language (UML), v1.1**. It's roots are in OOP. It's evolution can be traced to the early 1990s. UML establishes a common language among stakeholders involved in the design of object-oriented software and systems. Subsequently, UML undergoes many revisions, with v2.5.1 coming out in December 2017. 

2002

Robert Martin publishes a book on Agile where he describes five principles of OOD. Sometime later, Michael Feathers coins the term **SOLID** as a useful way to remember the principles.