Principles of Object-oriented Programming

  • Last Updated: August 4, 2023
  • By: javahandson
  • Series
img

Principles of Object-oriented Programming

In this article, we will learn about the principles of object-oriented programming with some basic examples.

 

If any programming language satisfies Object-oriented programming principles then we can call that language as an Object-oriented programming language. Java is an Object-oriented programming language as it satisfies those principles.

List of principles

  • Class
  • Object
  • Encapsulation
  • Abstraction
  • Inheritance
  • Polymorphism
  • Dynamic Binding
  • Message Passing

We will explore these principles in the below sections

Class

A Class is the most important concept of Java programming. Without a Class, we cannot create any programs.

A Class is a collection of data members and methods. The process of binding data members and their associated methods into a single unit is called Class.

Class is a User-defined data type that can store multiple values. These values can be of the same data type or different. When we create a class no memory is assigned to the data members and its methods. Memory gets assigned when we create an Object for that class. Hence we can say Class is just a template or a logical entity where data members are the attributes and the methods are known as behaviors.

Syntax

To create a Class we have to use the class keyword.

class <classname> {
 // variable declarations;
 // method definitions;
}

class is a keyword to create a Class. Class is a user-defined data type.

<classname> is a valid variable name. This will be the name of the Class.

variable declarations are the data members or attributes of the class.

If we have to perform any logical or business operations on the data members then we can create methods and perform the operations there. Methods should be always present within the scope of the class we cannot define them outside the class.

package com.javahandson.oops;
public class Employee {
    String name;
    String designation;
    float salary;

    float getBaseSalary() {
        return 45000f;
    }

    float getGrossSalary() {
        return 50000f;
    }
}

Object

The Object is an instance of Class. Without class, we cannot create an Object. When we create a Class, memory will not be assigned to the data members and their methods. Memory will be assigned to the members when we create an Object of the Class. This is the reason we say Class is a logical entity whereas Object is a physical entity.

An Object represents a different state and common behavior of the Class.

In the above example, we have created an Employee class. In a company, there will be multiple employees. So we can create multiple instances of the Employee class.

One instance will be for employee Rohit. Another instance will be for employee Virat and so on.

Here the state differs for both Objects as one Object is having data on Rohit whereas the other is having data on Virat. But the characteristics will be the same which means both the Objects will have gross salary and base salary just the data will differ.

Creating an Object

We can create an Object using a new operator. When we create an Object memory will be assigned to the class members. This is also known as dynamic memory allocation.

There are 2 different ways to create an Object using a new operator

Syntax: 1

<classname> <objectname> = new <classname()>;
Ex. Employee employee = new Employee();

The employee is the object name or reference name using which we can call the data members and their methods.

Syntax: 2

<classname> <objectname>; // Line 1
<objectname> = new <classname()>; // Line 2

Employee employee; 
employee = new Employee();

Line 1 does the Object declaration, at this point, the memory is not assigned. Here the object or reference name will point to null. In Line 2 we have used the new operator here the actual memory will be assigned to the Class members and the reference will point to the actual Object with the default values.

Note* We will learn about the default values later

package com.javahandson.oops;
public class Employee {

    String name;
    String designation;

    float getBaseSalary() {
        return 45000f;
    }

    float getGrossSalary() {
        return 50000f;
    }

    public static void main(String[] args) {

        Employee employee = new Employee();

        employee.name = "Suchit";
        employee.designation = "Developer";

        System.out.println("Employee name :"+employee.name);
        System.out.println("Employee designation :"+employee.designation);
        System.out.println("Employee base salary :"+employee.getBaseSalary());
        System.out.println("Employee gross salary :"+employee.getGrossSalary());
    }
}

Output :

Employee name :Suchit
Employee designation :Developer
Employee base salary :45000.0
Employee gross salary :50000.0

Encapsulation

The process of binding data and corresponding methods into a single unit is known as encapsulation. This process also helps to hide the information from external users to prevent unauthorized modification.

We can bind the data and methods into a single unit using the Class feature which we have already discussed above.

To hide the data in the class we use the private keyword. If we make the data member private then we can use that member within the class, we cannot use that member outside of that Class. If we want to use the private member outside of the Class then we can only do that using public setter and getter methods.

Since we cannot use the private variables outside the Class so no other Class can modify those variables directly.

We can make use of setter methods to set the values of private variables from other classes but we can add extra validations on that setter method so that the variables consume authorized data.

Advantages of encapsulation

  • We can achieve data member security
  • Improves the maintainability of the application as maintaining methods will be easier than variables.
  • Enhancement of the application becomes easy as the Class can be extended and new features can be added.
package com.javahandson.oops;
class Employee {

    private String name;
    private String designation;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }
}

public class Demo {
    public static void main(String[] args) {
        Employee employee = new Employee();

        employee.setName("Suchit");
        employee.setDesignation("Developer");

        System.out.println("Employee name :"+employee.getName());
        System.out.println("Employee designation :"+employee.getDesignation());
    }
}

Output :

Employee name :Suchit
Employee designation :Developer

Abstraction

The process of hiding the lower-level details and just showing the higher-level details is known as Abstraction. It also means we will just show the functionality to the user but we will not show how the implementation is done or how it functions.

Ex. For driving a car we just need to know how to use the functionality of the car like how to use clutch, brakes or gears etc but for driving we need not know how the engine works or what happens when we press the clutch. All this happens internally but as a user, we will not know how it happens. So this is called hiding the lower-level details.

Abstraction can be achieved in Java using abstract classes and interfaces.

Abstract Class will have abstract methods as well as non-abstract methods. Abstract methods will not have any definitions they will just have method declarations. Non-abstract methods are the normal methods that will have some definition.

The interface will have only abstract methods.

Abstract Classes and Interfaces will be implemented by some other Class and the implementor Class will give the definition to those abstract methods.

public abstract class Employee {
    private String name;
    private String designation;

    abstract float calculateSalary();
}

Note* Here Employee can be of any company so salary calculation is kept abstract because salary will be calculated based on that company’s pay scale.

Please check the articles on Abstract class and Interface to understand the topics in more depth.

Inheritance

The process of inheriting the data members and methods from one Class to another is known as inheritance.

Ex. Child can inherit the property from his Parent. In the same way, One Class can inherit the properties from another Class.

Parent Class or Super Class or Base Class – From whom the property can be inherited

Child Class or Sub Class or Derived Class – One who inherits the property

extends keyword is used for inheritance in Java.

Ex. Son extends Father

Son is the Derived Class and Father is the Base Class

When the properties are inherited it does not take any extra memory. Base class features are available to derived classes without taking any extra memory space as Java uses logical memory management to manage the inherited properties.

Advantages of Inheritance

  • We can reuse the existing codebase
  • Lessens the development time
  • Application performance is increased
  • Application memory space will be less
package com.javahandson.oops;
abstract class Employee {
    private String name;
    private String designation;
    abstract float calculateSalary();
}

class Microsoft extends Employee {
    @Override
    float calculateSalary() {
        return 50000;
    }
}

public class Demo {
    public static void main(String[] args) {

        Microsoft microsoft = new Microsoft();
        System.out.println("Microsoft employee salary : "+microsoft.calculateSalary());
    }
}

Output : Microsoft employee salary : 50000.0

Please check the article on Inheritance to understand the topic in more depth.

Polymorphism

Polymorphism means one name and multiple forms. It also means performing a single action in multiple ways.

Ex. Calculating the area of shapes. For calculating the area we will create a method but the same method cannot be used to calculate the area of a square, rectangle, triangle etc. So we will create separate area methods for each shape. Here function name is the same i.e. area but the logic is different for different shapes.

Types of polymorphism

Static or Compile time polymorphism – The Object will be bound to methods at compile time. Method signature will be different hence Java will figure out which method to call based on method signature at the compile time.

Compile time polymorphism can be achieved using method overloading. When there are multiple methods with the same name but different arguments then it is known as method overloading.

package com.javahandson;
public class Test {

    int area(int side) {
        return side * side;
    }

    int area(int length, int breadth) {
        return length * breadth;
    }

    public static void main(String[] args) {
        Test test = new Test();
        System.out.println("Area of square : "+test.area(4));
        System.out.println("Area of rectangle : "+test.area(4, 2));
    }
}
Output : Area of square : 16
Area of rectangle : 8

Dynamic or Runtime polymorphism – The Object will be bound to methods at run time. Runtime polymorphism concept cannot be achieved in a single Class it will be used at the hierarchical level. Method signature will be the same here that is the reason the Java compiler cannot figure out which method to call at compile time.

Runtime polymorphism can be achieved using method overriding. When there are multiple methods with the same name and same arguments then it is known as method overriding. What method to be called by JVM depends on the instance of the object which we will have at runtime that is the reason it is known as Runtime polymorphism.

package com.javahandson;

interface ShapeArea {
    int area(int side);
}

class Square implements  ShapeArea {
    public int area(int side) {
        return side * side;
    }
}

class Cube implements  ShapeArea {
    public int area(int side) {
        return side * side * side;
    }
}
public class Test {
    public static void main(String[] args) {
        ShapeArea square = new Square();
        System.out.println("Area of square : "+square.area(4));

        ShapeArea cube = new Cube();
        System.out.println("Volume of cube : "+cube.area(4));
    }
}

Output : Area of square : 16
Volume of cube : 64

In the above example, we can see based on the Object instance the method is called at runtime.

Dynamic Binding

Dynamic Binding is the same as Runtime polymorphism. The Object will be bound to the method at runtime that is why it is known as dynamic binding.

Message Passing

Message passing is a form of communication between 2 entities. We will send a message or Object from one entity and the other entity will receive it. The one who sends the message is known as the producer whereas the one who receives the message is known as the consumer. Message passing can be used in interthread communication or socket programming or remote procedure calls.

In the Interthread communication one thread will produce the Object and the other thread will consume that Object to perform some desired action. In the same way, when we do socket programming first program will write the data to the stream and the second program will consume the data from the stream and perform the desired operation.

Please check the article on Interthread communication to understand this topic in more depth.

So this is about the principles of object-oriented programming in Java. I hope you like the article. If you are having any questions on this topic please raise them in the comments section.

Leave a Comment