Articles

Introduction to OOP

The purpose of this article is to teach the concepts of the Object Oriented Programming (OOP) to a novice programmer as quickly and easily as possible.

Additionally, this information will help you to refresh your knowledge and possibly to prepare you for a job interview.

Note: The examples of code are made using C# programming language.

Long ago, in ancient times, there was a procedural programming.

This very phenomenon was quite suitable for solving simple problems of the old world, such as the simplest mathematical calculations. For a visual example, here is the code of a small program that allows us to calculate the average grade of a class.

// Simple program to calculate class average


// local variables
string? input = String.Empty;
int[] marks;
int sum = 0;
float average = 0;

// get marks
Console.WriteLine("Please enter the marks, separated by comma(,):");

try
{
    input = Console.ReadLine();

    // place marks into array
    if (!string.IsNullOrEmpty(input))
        marks = Array.ConvertAll(input.Split(','), int.Parse);
    else
    {
        System.Console.WriteLine("Error. No marks entered.");
        return;
    }

    // compute sum
    for (int i = 0; i < marks.Length; i++)
    {
        sum += marks[i];
    }

    // compute average
    average = sum / marks.Length;


    // show output
    Console.WriteLine("Sum is " + sum.ToString());
    Console.WriteLine("Average is " + average.ToString());
}
catch (Exception)
{
    Console.WriteLine("Garbage in, garbage out.");    
}

In our program, we used an array for entering marks, and a few basic variables.
But what if we would like to expand our application by including the ability to display the data of all, or a particular student?

As you know, each student is provided with certain data, such as First Name, Last Name, and Student Number. Let us add to this, that everyone has studied one or another subject and has received marks during the exams.

How to store and manage such a mass of information?

OOP comes to the rescue

Object Orientation Programming allows, in addition to primitive types of variables, to use objects.

To understand the difference, imagine a situation when someone asks you to describe a picture by giving you a box with individual pieces of a puzzle. It will take you a lot of time to get a complete picture from individual pieces of puzzle first. Only then can you give out information about what you saw on it. What if you had a complete picture right away? Then everything is much simpler.

The pieces of a puzzle are our primitive variables, and the whole picture is our object.

Therefore, having come to a new level of development, programming languages have acquired the ability to have a new type of variables, the type OBJECT.

An object is inherently a separate class.

What is a class?

A class is a blueprint or model, based on which, one or another object is created.

Thus, having complete information about a car, including a description of parts, drawings and the desired qualities, we can actually build a car.

class blueprint

The usual class consists of Properties, Constructors, and Methods.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleConsole
{
    public class Car
    {
        // Properties
        public string Model { get; set; }   
        public string Color { get; set; }
        public int NbWheels { get; set; }
        public int MaxSpeed { get; set; }

        // Constructors
        public Car()
        {

        }

        public Car(string model, string color)
        {
            Model = model;
            Color = color;
        }

        // Methods
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Car model is: {0}{1}", this.Model, Environment.NewLine);
            sb.AppendFormat("Car color is: {0}{1}", this.Color, Environment.NewLine);
            sb.AppendFormat("Car number of wheels is: {0}{1}", this.NbWheels, Environment.NewLine);
            sb.AppendFormat("Car maximum speed is: {0}{1}", this.MaxSpeed, Environment.NewLine);

            return sb.ToString();
        }

    }
}


Properties

In the example above, we created the class Car.

For the sake of simplicity, we limited ourselves to only: Model, Color, Number of Wheels and Maximum Speed. These characteristics are properties of our class.

At will, we can learn about the property of a certain car built according to this drawing, through the built-in GET method.

We can also change a specific property at any time using the built-in SET method.

If we want to prohibit calling or changing a certain property, we will need to remove GET or SET, respectively, simply by erasing it inside curly braces.

Constructors

A class can have one or many constructors. Constructors are used to create objects from a class.

They are a kind of method capable of taking parameters. By default, in a regular class there is at least one empty constructor, with no parameters.

In the example above, we created two different cars, using two different constructors that we have.

Car myCar1 = new Car();
Car myCar2 = new Car("Oldsmobile", "Silver");

The variables myCar1 and myCar2 are of the type of our class Car.

It is not enough to simply declare them as in the case of primitive types, but you need to create them by calling the constructor using the keyword new.

Methods

The ToStirng () method, which we added to our class, allows us to display the properties of an object created from a class.

Console.WriteLine("myCar1:");
Console.WriteLine(myCar1.ToString());
Console.WriteLine("**************************");
Console.WriteLine("myCar2:");
Console.WriteLine(myCar2.ToString());
Console.ReadLine();
oop_car_console

The first car has no characteristics, while the second has only those specified in the constructor.

At any time, as mentioned above, the properties of objects can be changed, if there is a built-in SET method inherent in this property.
Let us see how it will look like in example.

Car myCar1 = new Car();
Car myCar2 = new Car("Oldsmobile", "Silver");

myCar1.Model = "Chevrolet";
myCar1.Color = "Blue";
myCar1.NbWheels = 4;
myCar1.MaxSpeed = 220;

myCar2.Color = "White";
myCar2.NbWheels = 4;
myCar2.MaxSpeed = 100;

Console.WriteLine("myCar1:");
Console.WriteLine(myCar1.ToString());
Console.WriteLine("**************************");
Console.WriteLine("myCar2:");
Console.WriteLine(myCar2.ToString());
Console.ReadLine();

In this example, we changed the original color of the second car, and supplied both cars with all the missing properties.

Three pillars which support the OOP

The basis of Object Orientation Programming are Encapsulation, Polymorphism, and Inheritance.

We will explain everything in order.

Encapsulation

Imagine the same car, and yourself, as a driver.

Your main tools will be: navigation bar, steering wheel, pedals and gear shifting.

The designers have designed the car so that you can manage it as comfortable as possible.

When you push the pedals, turn the steering wheel and switch gears, you do not see what is happening behind the scenes, and how exactly the various mechanisms interact with each other at this time.

And you do not need to crawl under the hood every time to monitor the condition of the car while driving, you just need to look at the panel.

Thus, the navigation bar and various vehicle management tools are intermediaries between the vehicle mechanism and you. You may not see and do not know how the car is designed from the inside, but you can interact with it through the tools that are provided to you.

This is essentially encapsulation.

In the case of OOP, a car will be a certain class or object, interaction with which will be possible only with the help of available properties or methods.

Polymorphism and Inheritance

Usually, any application consists of a set of classes, which in turn can be divided into categories.

Imagine that our application should manage a certain fleet of vehicles. The park itself consists of various types of transport, which are divided into: cars, trucks, buses, all-terrain vehicles, and so on. Each of these types of transport has its own characteristics peculiar to it alone, as well as common to all.

Any vehicle has such characteristics as speed, spaciousness, color and model. However, most often, the floating machines have neither wings nor wheels, the passenger car does not have a cargo platform, just as there are no helicopters with caterpillars.

When developing a system, we will need to create a class for each type of transport. And everything would be fine if we were not faced with the problem of repeating the same properties and moving from one class to another.

In the case of a truck, a bus and a passenger car, it would have to be repeated with the number of wheels, model, color, capacity. But what if we accidentally forgot to assign the Number of Wheels property to the Bus class?

This is how the heritage came about.

The easiest way to bring an analogy with the parent and child. The child inherits from the parent certain common features that make them similar.

Also in the case of classes, when a certain parent class transfers its properties to its child classes.

So in order to avoid repetitions and errors, as well as to facilitate the work, we will create a parent class for the inventory of our fleet, and force each daughter to inherit common properties.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleConsole
{
    public class Transport
    {
        public string Model { get; set; }
        public string Color { get; set; }
        public int MaxSpeed { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleConsole
{
    public class Car : Transport
    {
        // Properties
        public int NbWheels { get; set; }

        // Constructors
        public Car()
        {

        }

        public Car(string model, string color)
        {
            Model = model;
            Color = color;
        }

        // Methods
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Car model is: {0}{1}", this.Model, Environment.NewLine);
            sb.AppendFormat("Car color is: {0}{1}", this.Color, Environment.NewLine);
            sb.AppendFormat("Car number of wheels is: {0}{1}", this.NbWheels, Environment.NewLine);
            sb.AppendFormat("Car maximum speed is: {0}{1}", this.MaxSpeed, Environment.NewLine);

            return sb.ToString();
        }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleConsole
{
    public class Bus : Transport
    {
        public bool IsLowFloor { get; set; }
    }
}

Above, we gave examples of three classes: Transport, Car, Bus.

Transport is the parent class, and the passenger car and the bus inherit common
properties and have their own, unique to them.

Well, everything seems to be clear with the legacy. Now, what is polymorphism?

In short, this is the possibility of an object to have several forms at once. What does it mean? In fact, this is very simple.

Polymorphism is directly related to inheritance, so the car, the bus and the truck are both separate objects and transport. This means that we can create a list of all vehicles in the fleet, and add to it both cars and buses with trucks.

Access specifiers

Classes are of different types and each has its own use in certain cases.

Now we will examine the main class specifiers in the C # language.

Static: does not allow to create objects. All methods are called directly from the class itself.

Abstract: Incomplete class. Must be completed in a class which is its successor.

Sealed: Forbids have heirs.

Partial: A class that can be split into several separate files. In general, all these files make up one single class.

It is usually used in the case when several developers are working simultaneously on a single class, each is responsible for their part.

Internal: Available only in its assembly, without going beyond its limits.

Protected: Available only for his heirs.

Method Specifiers

Virtual: a virtual method that can be rewritten by a descendant class.

Override: rewritten by the class derived from the method

Additionally

Reflections: used to examine an object, listing its properties in a cycle.
The default object methods that can be rewritten are: toString (), Equals ().