Open Closed Principle in Java with Examples

27 Aug, 2021
In software development, the use of object-oriented design is crucial. It helps to write flexible, scalable, and reusable code. It is recommended that the developers follow SOLID principles when writing a code. One of the five SOLID principles is the open/closed principle. The principle states that software entities like class, modules, functions, etc.; should be able to extend a class behavior without modifying it. This principle separates the existing code from modified mode to provide better stability, maintainability and minimizes the changes in the code. In a nutshell, the developer must need to change only a specific part of the code (a class or a function) every time a requirement changes.
Using a statically typed language like Java, C#, etc. the open/closed principle is generally achieved by using inheritance and polymorphism. Let’s understand it with a few examples.
Implementation: 
Program to calculate the volume in which let us consider the task of building an application that calculates the volumes of all the geometric objects.
The Cuboid class stores dimensions of the cuboid
Later on, the Application class calculates the total volume of the geometric objects–which are only cuboids currently.
Run class helps to run the whole program.
Example 1:
Java
// Java Program to illustrate Open Closed Principle // Class 1// Helper class// To store dimensions of a cuboid// length, breadth and heightclass Cuboid {         // Member variables    public double length;    public double breadth;    public double height;} // Class 2// Helper class// To calculate the volume of geometric objectsclass Application {     // It returns the total volume of the geometric objects    public double get_total_volume(Cuboid[] geo_objects)    {        // Variable to store total volume        double vol_sum = 0;         // Iteratively calculating the volume of each object        // and adding it to the total volume        for (Cuboid geo_obj : geo_objects) {                         // Iteratively calculating the volume of each object            // and adding it to the total volume            vol_sum += geo_obj.length * geo_obj.breadth                       * geo_obj.height;        }         // returning the to total volume        return vol_sum;    }} // Class 3// Main Class// To demonstrate working of all classespublic class GFG {     // Main driver method    public static void main(String args[])    {        // Initializing a cuboid one & declaring dimensions by        // creating an object of Cuboid class in main() method        Cuboid cb1 = new Cuboid();         // Custom entries        cb1.length = 5;        cb1.breadth = 10;        cb1.height = 15;         // Similarly, initializing a cuboid2 and declaring dimensions        // by creating object of Cuboid class in the man() method        Cuboid cb2 = new Cuboid();         // Custom entries        cb2.length = 2;        cb2.breadth = 4;        cb2.height = 6;         // Initializing a cuboid3 and declaring dimensions by        // creating object of Cuboid class in the main() method        Cuboid cb3 = new Cuboid();         // Custom entries        cb3.length = 3;        cb3.breadth = 12;        cb3.height = 15;         // Now, declaring andinitializing Array of cuboids        Cuboid[] c_arr = new Cuboid[3];        c_arr[0] = cb1;        c_arr[1] = cb2;        c_arr[2] = cb3;         // Initializing the Application class        Application app = new Application();                 // Getting the total volume        // using get_total_volume        double vol = app.get_total_volume(c_arr);                 // Print and Display the Total Volume        System.out.println("The total volume is " + vol);    }}
The total volume is 1338.0
Now, lets say the customer wants the application to calculate the volume of a sphere as well. In order to accommodate new type of geometric object, the application also needs to be changed.
Example 2:
Java
// Java Program to illustrate Open Closed Principle // class 1// Helper class// To store dimensions of a cuboid// used to store length, breadth and height of a cuboidclass Cuboid {     // Member variables of this class    public double length;    public double breadth;    public double height;} // Class 2// Helper class// To store dimensions of a sphereclass Sphere {     // Storing radius of a sphere    public double radius;} // Class 3// Helper class// This class helps to calculate the volume of geometric// objectsclass Application {     // Returning the total volume of the geometric objects    public double get_total_volume(Cuboid[] c_geo_objects,                                   Sphere[] s_geo_objects)    {        // Variable used to store total volume        double vol_sum = 0;         // Iteratively calculating the volume of each Cuboid        // and adding it to the total volume         // Iterating using for each loop to        // calculate the volume of a cuboid        for (Cuboid geo_obj : c_geo_objects) {             vol_sum += geo_obj.length * geo_obj.breadth                       * geo_obj.height;        }         // Iterating using for each loop to        // calculate the volume of a cuboid        for (Sphere geo_obj : s_geo_objects) {             // Iteratively calculating the volume of each            // Sphere and adding it to the total volume            vol_sum += (4 / 3) * Math.PI * geo_obj.radius                       * geo_obj.radius * geo_obj.radius;        }         // Returning the to total volume        return vol_sum;    }} // Class 4// Main class// To demonstrate working of all classespublic class GFG {     //  Main driver method    public static void main(String args[])    {        // Initializing a cuboid one as well as declaring        // its dimensions.        Cuboid cb1 = new Cuboid();        cb1.length = 5;        cb1.breadth = 10;        cb1.height = 15;         // Initializing a cuboid two as well as declaring        // its dimensions.        Cuboid cb2 = new Cuboid();        cb2.length = 2;        cb2.breadth = 4;        cb2.height = 6;         ////Initializing a cuboid three as well as declaring        /// its dimensions.        Cuboid cb3 = new Cuboid();        cb3.length = 3;        cb3.breadth = 12;        cb3.height = 15;         // Initializing and declaring an array of cuboids        Cuboid[] c_arr = new Cuboid[3];        c_arr[0] = cb1;        c_arr[1] = cb2;        c_arr[2] = cb3;         // Initializing a sphere one as well as declaring        // its dimension.        Sphere sp1 = new Sphere();        sp1.radius = 5;         // Initializing a sphere two as well as declaring        // its dimension.        Sphere sp2 = new Sphere();        sp2.radius = 2;         // Initializing a sphere three as well as declaring        // its dimension.        Sphere sp3 = new Sphere();        sp3.radius = 3;         // Initializing and declaring an array of spheres        Sphere[] s_arr = new Sphere[3];        s_arr[0] = sp1;        s_arr[1] = sp2;        s_arr[2] = sp3;         // Initializing Application class        Application app = new Application();         // Getting the total volume        // using get_total_volume        double vol = app.get_total_volume(c_arr, s_arr);         // Print and display the total volume        System.out.println("The total volume is " + vol);    }}
The total volume is 1840.6548245743668
Output Explanation:
As we can see the application class had to be changed to accommodate the sphere. Any changes in a code can lead to some unexpected errors in the future–so it is not advisable to change the well-tested code every time requirements change. Let’s try to apply the Open Close principle and see if we can add a sphere (a new type of object) without making any changes to the application class.
Solution:
Create an abstract class that serves as a base class for all types of objects.
All the geometric objects have a set of dimensions and a get_volume method (both of which are different for each type of object).
For each type of object (a geometric object in this case) inherit the ‘Geo_object’ class, add the dimensions for that type of object and override the ‘get_volume‘ method.
As it is apparent that by shifting the volume calculation from the ‘Application’ class to a different class, adding a new type of geometric object would not require changing the ‘Application’ class.
Example 3:
Java
// Java Program to illustrate Open Closed Principle // Importing all classes from java.math package// to compute mathematic calculationsimport java.math.*; // Class 1// Helper Class// Abstract class--which needs to be extendedabstract class Geo_objects {    // Abstract function--which needs to overriden    public abstract double get_volume();} // Class 2// Helper Class// Extending the Geo_objects to fit cuboid dimensionsclass Cuboid_2 extends Geo_objects {         // used to store length, breadth and height of a cuboid     public double length;    public double breadth;    public double height;     // overrided function to calculate    // the volume of a cuboid    // @Override    public double get_volume()    {        return length * breadth * height;    }} // Class 3// Helper Class// Extending Geo_objects to fit sphere dimension class Sphere_2 extends Geo_objects {         // To store radius of a sphere    public double radius;     // Overrided function to calculate    //  the volume of a sphere         //@Override    public double get_volume()    {        return (4 / 3) * Math.PI * radius * radius * radius;    }} // Class 4// Helper class// To calculate the volume of geometric objectsclass Application {     public double        get_total_volume(Geo_objects[] geo_objects)    {        // Initially initializing sum to zero        double vol_sum = 0;         // Iterating using for each loop        for (Geo_objects geo_obj : geo_objects) {            vol_sum += geo_obj.get_volume();        }          return vol_sum;    }} // Class 5// Main class// To demonstrate working of all classespublic class GFG {     // Main driver method    public static void main(String args[])    {        // Initializing cuboid1 as well as declaring        // its dimensions.        Cuboid_2 cb1 = new Cuboid_2();         // Custom entries        cb1.length = 5;        cb1.breadth = 10;        cb1.height = 15;         // Initializing Cuboid2 as well as declaring        // its dimensions.        Cuboid_2 cb2 = new Cuboid_2();        cb2.length = 2;        cb2.breadth = 4;        cb2.height = 6;         // initializing Cuboid3 as well as declaring        // its dimensions.        Cuboid_2 cb3 = new Cuboid_2();        cb3.length = 3;        cb3.breadth = 12;        cb3.height = 15;         // initializing Sphere1 as well as declaring        // its dimension.        Sphere_2 sp1 = new Sphere_2();        sp1.radius = 5;         // initializing Sphere2 as well as declaring        // its dimension.        Sphere_2 sp2 = new Sphere_2();        sp2.radius = 2;         // initializing Sphere3 as well as declaring        // its dimension.        Sphere_2 sp3 = new Sphere_2();        sp3.radius = 3;         // Now, initializing and declaring        // an array of Geo_objects        Geo_objects[] g_arr = new Geo_objects[6];         // Setting Geo_objects to cuboid class        g_arr[0] = cb1;        g_arr[1] = cb2;        g_arr[2] = cb3;         // Setting Geo_objects to sphere class        g_arr[3] = sp1;        g_arr[4] = sp2;        g_arr[5] = sp3;         // Initializing the Application class        Application app = new Application();                 // Getting the total volume        // using get_total_volume        double vol = app.get_total_volume(g_arr);         // Printing total volume        System.out.println("The total volume is " + vol);    }}
The total volume is 1840.6548245743668
Output Explanation:
The Application class is closed for modification. Please note there may be other ways to achieve the Open Close principle–ours is just one of the possible approaches.
On taking an overview, we found that our first approach wasn’t open for extension and required modification in the code to accommodate new requirements (new geometric objects) . While the second approach was open for extension and adding new requirements can be done without modifying any existing code. The second approach helps to achieve robustness in the whole program.
anikaseth98
surinderdawra388
Picked
Java
Java
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.