Programming

Object Oriented Programming

Object-oriented programming (OOP) is a computer programming style that represents systems as “objects”. These objects have data fields and associated procedures known as methods.

Data fields (or attributes) describe the object while methods represent what the object is capable of doing.

For a “Person” class, attributes may include: name, height, gender, age, date of birth, phone number and so on. While associated methods may include: eat, move, read, sleep, have sex etc.

This article will use Java programming language to demonstrate the concepts of OOP.

What is an Object?

An Object is an instance of  a Class.

What is a Class

A Class can be thought of as the blueprint of an Object.

For example, the blueprint of house can be used to build a house. With the same blueprint you can build unlimited copies of the same house and they would look alike. This is class instantiation.

Instantiation is when you create an object from a class.

In summary, a class is a unit of code that can contain attributes, methods, and all other code syntax.

Why do it like this?

A computer only understands Binary Code (1 and 0). Programmers of yore wrote programs in binary code.

The problem? Binary is hard to write. It is tedious, error prone and hard to read.

Machine code is so unreadable that the United States Copyright Office cannot identify whether a particular encoded program is an original work of authorship

Pamela Samuelson – Professor of Law

Looking at a program written in machine language (binary code) is vaguely comparable to looking at a DNA molecule atom by atom.

Douglas Hofstadter – Professor of Cognitive Science

Smart people invented, programming languages that are closer to human language and also invented different styles of programming to make developing software easier to write and read, modular and maintainable.

The most popular style of programming is OOP.

Why is OOP so popular?

OOP is Popular because it combines procedural style of programming with the concept of classes.

OOP makes it easier for us to write code that is:

  1. easy to understand
  2. easy to modify
  3. easy to debug
  4. easy to model complex systems

The philosophy of OOP can be used to build software in any other Imperative style of programming like C, but it is easier to implement in languages that support OOP natively like C++, Java etc.

In object oriented programming, importance is given to data rather than just writing instructions to complete a task (as seen in procedural style of programming). An object is a thing or idea that you want to model in your program. An object can be anything: person, employee, bank account, car etc.

Example 1

The code below is a class. It models a Car, in Java.

class Car{
 private String carMaker;
 private String modelName; 
 private String color;
 private float topSpeed;

  // we will implement a constructor later.

  public void accelerate(){
    // define how a vehicle should accelerate
  }
  public void brake(){
    // define how a vehicle should come to a halt
  }
}

Model name, color and top speed are attribute that define our Car class.

Cars must posses the ability to accelerate and brake, hence the methods

The code below shows how to create an Object from our defined Class.

Car poloCar = new Car ("Forda", "polo", "Green",  200);
Car miniCar = new Car ("Toyoti", "mini", "Blue",  185);
Car beetleCar = new Car ("Masdi", "beetle", "Red",  165);

Polo Car, Mini Car, Beetle Car are all objects of Car class.

For the Polo Car we created a car made by “Forda”, with the model name “polo”, it is color “green” and has a top speed of “200” km/h. Same goes for the other objects.

From the “Car” class, we can create many types of Car objects as we want and define unique characteristics for each.

Pillars of OOP

  1. Inheritance
  2. Abstraction
  3. Encapsulation
  4. Polymorphism

1. Inheritance

Imagine you want to build a vehicle management system.

Motor vehicles (motorcycles, cars, trucks, buses), railed vehicles (trains, trams), watercraft (ships, boats), amphibious vehicles (screw-propelled vehicle, hovercraft), aircraft (airplanes, helicopters) and spacecraft are all examples of vehicles.

You could follow the example (on Cars) above and model for every kind of vehicle but it would be exhausting because there are tens of thousands of different car models by different companies and that would violate the Do not Repeat Yourself (DRY) principle.

DRY is a basic principle of software development aimed at reducing repetition of information. The DRY principle is stated as, “Every piece of knowledge or logic must have a single, unambiguous representation within a system.”

Inheritance is a concept that helps classes to be organized into a hierarchies and enabling these classes to inherit attributes and behavior from classes above in the hierarchy.

What do all Vehicles have in common? They transport people and goods from one place to another, which means they have speed, space for people or goods, they use fuel and other similarities.

public class Vehicle {
    String vehicleType;
    float fuelCapacity;
    float maximumHorsePower;
    float maximumMetricCapacity;
    float maximumWeightLimitKg;
    float velocity;
    float acceleration;
    
    public void accelerate(){};
    public void brake(){};
}

The class above models a Vehicle.

The code below inherits from Vehicle.

In java, the extends keyword is used to inherit a class. as shown below.

public class Airplane extends Vehicle{
    Boolean hasOxygenMask;
    Boolean hasParachute;

    public void makeAnnouncements(String message){}
    public void takeOff(){}
    public void touchDown(){}
}

The Airplane class above inherits all the properties of Vehicle without having to define it. It is now left for us to implement features that are Airplane specific like make announcements (we pass in the message we would like to communicate), take off, touch down etc.

When you inherit a class you can override the default methods and provide you own implementation of the method.

Access modifiers control whether you can or cannot do this. Read more about access modifier under ENCAPSULATION.

public class Airplane extends Vehicle{

    @Override
    public void accelerate() {
        super.accelerate();
        // define a custom implementation of 
        // how an Airplane should Accelerate
    }
}

This is useful in situations where there’s a unique sub class that does not function as the rest of the other sub classes.

1.1 The “Super” Keyword

Within the overridden accelerate method you see the code super.accelerate(). That line of code means, execute all the code accelerate method in the super class (inherited class). Yes you can remove it.

The super keyword can also let you access the variables of the super class. You can manipulate vehicle type variable from within Airplane class as shown below:

public class Airplane extends Vehicle{
    @Override
    public void accelerate() {
        super.accelerate();
        super.vehicleType = "AirPlane"; // this line
    }
}

And finally, the super can let you call the constructor of the super class.

a Constructor is a special type of method – within the class itself – called to create an object. It prepares the new object for use, often accepting arguments that the constructor uses to set required member variables.

public class Vehicle {
    private String vehicleType;
    private float fuelCapacity;
    private float maximumHorsePower;
    private float maximumMetricCapacity;
    private float maximumWeightLimitKg;
    private float velocity;
    private float acceleration;


    public Vehicle //the constructor method
            (String vehicleType, 
             float fuelCapacity, 
             float maximumHorsePower, 
             float maximumMetricCapacity, 
             float maximumWeightLimitKg, 
             float velocity, float acceleration) {
        
        
        this.vehicleType = vehicleType;
        this.fuelCapacity = fuelCapacity;
        this.maximumHorsePower = maximumHorsePower;
        this.maximumMetricCapacity = maximumMetricCapacity;
        this.maximumWeightLimitKg = maximumWeightLimitKg;
        this.velocity = velocity;
        this.acceleration = acceleration;
        
    }

    public void accelerate(){};
    public void brake(){};
}

The constructor lets us initialize all or some of our variables immediately an object is created. In code you must supply all of those data before you can create an object.

Vehicle vehicle = new Vehicle("Car", 30, 220, 300, 400, 0, 0);

The code above creates a new Vehicle. Vehicle type is Car, has fuel capacity of 30 liters, maximum horse power of 220, maximum volume 300 cubic meters, maximum weight limit of 400 Kg, a velocity and acceleration of zero because it is not yet in motion.

If we inherit a class with a constructor we must supply the needed values to the constructor of the super class. The super helps us to achieve that as shown below.

public class Car extends Vehicle{

    public Car() {
        super("Car", 30, 220, 300, 400, 0, 0); // same as above
    }
}

Every object of car create will have those default values

2. Polymorphism

Polymorphism comes from a greek word, that mean: to take more than one form

For example, all vehicles can move but how an airplane moves is different from how a car or motorcycle moves but they both move.

Inheritance is one means of achieving polymorphism where method defined in the inherited class can be overridden by writing a custom implementation of the method. 

public class Car extends Vehicle{

    @Override
    public void accelerate() {
        // Code goes here 
    }
}

The code above, overrides the accelerate method in the Vehicle class to implement how exactly a car should accelerate while the code below exact same thing for an airplane class.

public class Airplane extends Vehicle{
    
    @Override
    public void accelerate() {
        // Code goes here
    }
}

From the examples above you can clearly see that the method accelerate() has taken many forms in different classes.

Polymorphism of a method can also take many forms within the same class as shown below.

public class Car extends Vehicle{
    String engineName;

    public void openDoor(){}
    public void openDoor(int location){}
    public void openDoor(int[] locations){}
}

The car above has a method to Open the doors of the car. The first open door method will open just the drivers door, while in the second method we have to specify the location of the door we want to open and in the third we can specify a locations of the doors we want to open at once.

Notice all of the methods have the same name? This is what is know as method overloading, an implementation of polymorphism.

public static void main(String[] args) {
    Car carObject = new Car();
    carObject.engineName = "V12"; //accessing variables

    carObject.openDoor();  // open driver door
    carObject.openDoor(4); // open doors 4 i.e back left door.
    car.openDoor(new int[]{2,3}); // open only door 2 and 3

}

In the preceding code snippet, the dot operator( . ), is used to access the variables and methods of the class.

3. Encapsulation

Encapsulation is all about exposing a solution to a problem without requiring the consumer to fully understand the problem domain.

Encapsulation protects your class from being used in a way that it wasn’t meant to be. It limits the access of a user to the internal working of the system.

In context, let’s say you have a “Person” class as below

public class Person{
    private int age;
            
    public void setDateOfBirth(int age) {
       if (age < 18){
           //return an error, this user cannot be registered
       }else{
          this.age = age; 
       } 
    }
}

In this fictional app, our application user need to be 18+.

Even though 7 is a valid age, we do not want users that young, to avoid going to jail, we will return an error message!

Also -1 is a valid integer it is not a valid age, we can also return an error.

By using the private keyword on age we have granted limited access to it.

Access modifiers gives us this super ability.

Encapsulation is achieved with the use of access modifiers. You may have noticed them in the examples above, they are:

  1. Default: this is applicable when no access modifier is given
  2. Public
  3. Private
  4. Protected

Access modifiers control access to our code.

In a car, we use the gear system everyday but do not know the specifics of how it works. That’s encapsulation.

The benefit of encapsulation is prevent users from doing things that the systems was not designed to do, to avoid errors and crashes.

Classes, methods and variables can be encapsulated

3.1 Class Encapsulation

A class can be encapsulated with either default or public keyword.

1. public: A class declared as public can be seen and accessed by all other classes.

public class Car{
}

2. default: A class has default access when no access modifier is specified. This will make the class seen and accessible to classes in the same package, but inaccessible to all other classes not in the same package.

class Car{
}

What is a package? A package in Java is used to group related classes. Think of it as a folder in a file directory

Diagram of Code Packages

ModelledData and MainProgram are two different packages.

if we try to create a car object from its class, which is default, we would get the following error: “Cannot be accessed from outside package”

not able to Create an object because its class has default access modifier

3.2 Method Encapsulation

A method can be encapsulated with either default, public, private or protected keyword.

1. default: this done with no access modifier specified specified. It can be used only by other classes in the same package.

public class Car {
     void accelerate(){
      // no access modifier stated for this method
     }
}

We would not be able to access accelerate method from MainCode because it is in different package, refer to Diagram of Code Packages.

It also cannot be overridden by a subclass in a different package.

Method cannot be accessed due to default access modifier

2. public: any class in any package can access the method, as long as the class also uses the public modifier. When default is used for classes, it does not matter the modifier you use for methods, other packages will not be able to access it.

3. private: this is used when you want the private method to be accessed by its class alone. Other classes will not be able to access it either by overriding it or using dot operator.

4. protected: this is used when you want only the methods to be accessed by members of the same package and when a class is inherited.

3.3 Variable Encapsulation

public: You guessed it! Any class or method from any package can see this variable. Use public only when you are sure that this is what you want.

protected: This is the next least restrictive modifier after public. protected Variables set as protected can be seen by any class and any method as long as they are in the same package.

default: This doesn’t sound as restrictive as protected, but it is more so. A variable has default access when no access is specified. The fact that default is restrictive perhaps implies that we should be thinking on the side of hiding our variables rather than exposing them. At this point, we need to introduce a new concept. Do you remember that we briefly discussed inheritance, and how we can quickly take on the attributes of a class and yet refine it using the extends keyword? Just for the record, default access variables are not visible to subclasses. This means that when we extend a class like we did with Activity, we cannot see its default variables. We will look at inheritance in more detail later in the chapter.

private: These variables can only be seen within the class they are declared. Like default access, they cannot be seen by subclasses (inherited classes).

Page 217 – Learning Java Building Android Games, 2nd edition – John Horton

4. Abstraction

Example 2

Summary & Conclusion

References & Credit

  1. https://dev.to/charanrajgolla/beginners-guide—object-oriented-programming
  2. Learning Java Building Android Games, 2nd edition – John Horton
Tags

Edge Developer

Hello there, my name is Opeyemi Olorunleke. I am a Software Developer (majorly Android, GitHub Profile), Digital Marketer, Udemy Instructor, Technical Writer, Blogger & Webmaster.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button
Close
Close