Java OOPS Concepts

OOPS Concept with Real Life Example:

This is the most asked Question in a technical interview in any domain. OOPs Concept is very important. Today I will explain OOPs concept with real Life Example that will help you to grasp the concept well and excel in the interviews…

Objects:

Object is the basic unit of object-oriented programming. Objects are identified by its unique name. An object represents a instance of a class. There can be more than one instance of an object. Each instance of an object can hold its own relevant data.

An Object is a collection of data members and associated member functions also known as methods.

Classes:

Classes are data types based on which objects are created. Objects with similar properties and methods are grouped together to form a Class. Thus a Class represent a set of individual objects. Characteristics of an object are represented in a class as Properties. The actions that can be performed by objects become functions of the class and is referred to as Methods.

Example #1: For example consider we have a Class of Cars under which Santro Xing, Alto and WaganR represents individual Objects. In this context each Car Object will have its own, Model, Year of Manufacture, Colour, Top Speed, Engine Power etc., which form Properties of the Car class and the associated actions i.e., object functions like Start, Move, and Stop form the Methods of Car Class. No memory is allocated when a class is created. Memory is allocated only when an object is created, i.e., when an instance of a class is created.

Abstraction

Abstraction is used to separate ideas from their implementation. Abstraction in java is used to define only ideas in one class so that the idea can be implemented by its sub classes according to their requirements. For example,

abstract class Animal{    abstract void soundOfAnimal();  // It is just an idea}
class Cat extends Animal{    void soundOfAnimal()    {        System.out.println(“Meoh”);        //Implementation of the idea according to requirements of sub class    }}
class Dog extends Animal{    void soundOfAnimal()    {        System.out.println(“Bow Bow”);        //Implementation of the idea according to requirements of sub class    }}

Abstraction in java is implemented using Abstract classes and interfaces.

Abstract Classes:

Abstract classes contain abstract methods (you can refer them as ideas) so that they can be implemented in sub classes according to their requirements. They are also called as incomplete classes as they have some unimplemented abstract methods (ideas).

Let’s discuss some rules need to follow while using abstract classes and abstract methods.

    Abstract classes and abstract methods are declared using ‘abstract ‘keyword.  We can’t create objects to those classes which are declared as abstract. But, we can create objects to sub classes of abstract class, provided they must implement abstract methods.

    abstract class AbstractClass    {        abstract void abstractMethod();    }         class ConcreteClass extends AbstractClass    {        void abstractMethod()        {            System.out.println("Abstract Method Implemented");        }    }         public class Abstraction    {        public static void main(String[] args)        {            //AbstractClass A = new AbstractClass();  Can’t create objects to Abstract class            ConcreteClass C = new ConcreteClass();            //ConcreteClass implements abstract method,            //so we can create object to ConcreteClass            AbstractClass A1 = C;            //ConcreteClass object is auto-upcasted to AbsractClass        }    }

    The methods which are not implemented or which don’t have definitions must be declared with ‘abstract’ keyword and the class which contains it must be also declared as abstract.

    // It gives compile time error    class AbstractClass    {        void abstractMethod();  //This method must be declared as abstract or must be defined        abstract void abstractMethod();  //The Class must be also declared as abstract    }         //      *****   *****     *****   *****    // This is OK    abstract class AbstractClass    {        abstract void abstractMethod();    }

    It is not compulsory that abstract class must have abstract methods. It may or may not have abstract methods. But the class which has at least one abstract method must be declared as abstract.

    abstract class AbstractClass    {        void methodOne()        {            //Concrete Method        }        //No Abstract methods but class is abstract    }

    You can’t create objects to abstract class even though it does not contain any abstract methods

    abstract class AbstractClass    {        void methodOne()        {            //Concrete Method        }             void methodTwo()        {            //Concrete Method        }    }         public class Abstraction    {        public static void main(String[] args)        {            AbstractClass a = new AbstractClass();  //Compile time error            //You can’t create objects to AbstractClass            //even though it does not contain any abstract methods.        }    }

    Any class extending an abstract class must implement all abstract methods. If it does not implement, it must be declared as abstract.

    abstract class AbstractClass    {        abstract void abstractMethodOne();  //Abstract Method             abstract void abstractMethodTwo();  //Abstract Method    }         class ConcreteClass extends AbstractClass    {        void abstractMethodOne()        {            //abstractMethodOne() is implemented        }             //This class must implement second abstract method also,        //otherwise, this class has to be declared as abstract             void abstractMethodTwo()        {            //abstractMethodTwo() is also implemented.            //No need to declare this class as abstract        }    }

    Inside abstract class, we can keep any number of constructors. If you are not keeping any constructors, then compiler will keep default constructor.

    abstract class AbstractClass    {        AbstractClass()        {            //First Constructor        }             AbstractClass(int i)        {            //Second Constructor        }             abstract void abstractMethodOne();  //Abstract Method    }

    Abstract methods can not be private. Because, abstract methods must be implemented somehow in the sub classes. If you declare them as private, then you can’t use them outside the class.

    abstract class AbstractClass    {        private abstract void abstractMethodOne();        //Compile time error, abstract method can not be private.    }

    Constructors and fields can not be declared as abstract.

    abstract class AbstractClass    {        abstract int i;        //Compile time error, field can not be abstract             abstract AbstractClass()        {            //Compile time error, constructor can not be abstract        }    }

    Abstract methods cannot be static.

abstract class AbstractClass    {        static abstract void abstractMethod();        //Compile time error, abstract methods can not be static    }

Interface:

Interfaces in java are very much similar to abstract classes but interfaces contain only abstract methods (you can refer to them as only ideas). Abstract classes may contain both abstract methods as well as concrete methods. But interfaces must contain only abstract methods. Concrete methods are not allowed in interfaces. Therefore, Interfaces show 100% abstractness.

Let’s discuss some of the points regarding Interfaces.

    Interfaces are declared with keyword ‘interface‘ and interfaces are implemented by the class using ‘implements‘ keyword.


interface InterfaceClass{    //Some Abstract methods}
class AnyClass implements InterfaceClass{    //Use ‘implements’ while implementing Interfaces    //Don’t use ‘extends’}

    Interfaces should contain only abstract methods. Interfaces should not contain a single concrete method.


interface InterfaceClass{    abstract void abstractMethodOne();  //abstract method
    abstract void abstractMethodTwo();  //abstract method
    void concreteMethod()    {        //Compile Time Error.        //Concrete Methods are not allowed in interface    }}

    Interface can have two types of members.  1) Fields     2) Abstract Methods.


interface InterfaceClass{    int i = 0;      //Field
    abstract void abstractMethodOne();  //abstract method
    abstract void abstractMethodTwo();  //abstract method}

    By default, Every field of an interface is public, static and final You can’t use any other modifiers other than these three for a field of an interface.


interface InterfaceClass{    int i = 0;    //By default, field is public, static and final
    //Following statements give compile time errors
    private double d = 10;    protected long l = 15;
    //You can’t use any other modifiers other than public, static and final}

    You can’t change the value of a field once they are initialized. Because they are static and final. Therefore, sometimes fields are called as Constants. (We will discuss this feature in detail while covering ‘final’ keyword)


interface InterfaceClass{    int i = 0;}
class AnyClass implements InterfaceClass{    void methodOne()    {        //Following statement gives compile time error.
        InterfaceClass.i = 10;
        //final field can not be re-assigned    }}

    By default, All methods of an interface are public and abstract.


interface InterfaceClass{    void abstractMethodOne();  //Abstract method
    void abstractMethodTwo();  //Abstract Method
        //No need to use abstract keyword,        //by default methods are public and abstract}

    Like classes, for every interface .class file will be generated after compilation.

    While implementing any interface methods inside a class, that method must be declared as public. Because, according to method overriding rule, you can’t reduce visibility of super class method. By default, every member of an interface is public and while implementing you should not reduce this visibility.


interface InterfaceClass{    void methodOne();}
class AnyClass implements InterfaceClass{    void methodOne()    {        //It gives compile time error.        //Interface methods must be implemented as public    }}

    By default, Interface itself is not public but by default interface itself is abstract like below,

    abstract interface InterfaceClass    {        //By default interface is abstract        //No need to use abstract keyword    }          

    SIB – Static Initialization Block and IIB – Instance Initialization Block are not allowed in interfaces


interface InterfaceClassOne{    static    {        //compile time error        //SIB’s are not allowed in interfaces    }
    {        //Here also compile time error.        //IIB’s are not allowed in interfaces    }
    void methodOne();  //abstract method}

    As we all know that, any class in java cannot extend more than one class. But class can implement more than one interfaces. This is how multiple inheritances are implemented in java.

 interface InterfaceClassOne{    void methodOne();}
interface InterfaceClassTwo{    void methodTwo();}
class AnyClass implements InterfaceClassOne, InterfaceClassTwo{    public void methodOne()    {        //method of first interface is implemented    }
    //method of Second interface must also be implemented.    //Otherwise, you have to declare this class as abstract.
    public void methodTwo()    {        //Now, method of Second interface is also implemented.        //No need to declare this class as abstract    }}

Encapsulation:

Encapsulation means which binds the data and code (or) writing operations and methods in single unit (class).

For Example:

A car is having multiple parts. Like steering, wheels, engine…etc. which binds together to form a single object that is car. So, here multiple parts of cars encapsulate itself together to form a single object that is Car.

In real time we are using Encapsulation for security purpose…

Encapsulation = Abstraction + Data Hiding.

Inheritance:

·        Deriving a new class from the existing class is called Inheritance.

·        Derived (sub class) class is getting all the features from Existing (super class\base class) class and also incorporating some new features to the sub class.

·        Inheritance represents the IS-A relationship which is also known as a parent-child relationship.

Why use inheritance in java

  • For Method Overriding (so runtime polymorphism can be achieved).
  • For Code Reusability.

Types of inheritance in java

On the basis of class, there can be three types of inheritance in java: single, multilevel and hierarchical.

In java programming, multiple and hybrid inheritance is supported through interface only.

Polymorphism:

In Greek, Poly means many and morph means shapes or forms. So Polymorphism refers to any entity which takes many forms.

Polymorphism in java refers to any entity whether it is an operator or a constructor or any method which takes many forms or can be used for multiple tasks either while compiling or while running a java program.

There are two types of polymorphism in Java.

1) Static Polymorphism       2) Dynamic Polymorphism.

 

1) Static Polymorphism

Any entity which shows polymorphism during compile time is called static polymorphism. Operator Overloading, Constructor Overloading and method overloading are best examples of static polymorphism. Because, they show polymorphism during compilation.

In static polymorphism, object used is determined during compilation itself. So, it is called static binding or Early Binding.

    Operator Overloading: For example, Operator ‘+’ can be used to add two numbers and also can be used to concatenate two strings. It is called operator overloading. ‘+’ is the only operator in java which is used for operator overloading.

    Constructor Overloading : We can include multiple constructors in a class. This is called constructor overloading. Through constructor overloading, we can create objects to the class in multiple ways. This shows the polymorphism.

    Method Overloading : We can have different forms of same method in the same class. This is called method overloading. Through method overloading we can perform different tasks through different forms of the same method. This shows the polymorphism.

In casting, we have seen super class reference variable can refer to objects of its sub class. This also shows polymorphism. For example,

class A{     //Some Statements}class B extends A{     //Some Statements}class C extends B{    //Some Statements}
public class D{    public static void main(String[] args)    {        A a = new A();  //A-Class variable refers to A-Class object        a = new B();    //A-Class variable refers to B-Class object        a = new C();    //A-Class variable refers to C-Class object    }}

2) Dynamic Polymorphism

Any entity which shows polymorphism during run time is called dynamic polymorphism. Method Overriding is the best example of dynamic polymorphism. It is also called dynamic binding or late binding, because type of the object used will be determined at run time only.

class SuperClass{    void methodOfSuperClass()    {        System.out.println(“From Super Class”);    }}class SubClass extends SuperClass{    //Super Class Method Overrided    void methodOfSuperClass()    {        System.out.println(“From Sub Class”);    }}
public class D{    static void util(SuperClass superclass)    {        superclass.methodOfSuperClass();        //For each execution of this method, different objects will be passed to it.        //which Object will be used is determined during run time only.        //This shows dynamic polymorphism.    }
    public static void main(String[] args)    {        SuperClass superclass1 = new SuperClass();        SubClass subclass = new SubClass();        SuperClass superclass2 = new SubClass();
        util(superclass1);  //SuperClass object is passes to util()        util(subclass);     //SubClass object is passed to util()        util(superclass2); //SubClass object is passed to util()    }}

Method Overloading:

Compiler checks method signature for duplicate methods or for method overloading. Method signature consist of three things, 1) Method Name   2) Number Of Arguments   3) Types of arguments.

Method Overriding In Java:

When a class extends its super class, all or some members of super class are inherited to sub class. When a inherited super class method is modified in the sub class, then we call it as method is overrided. Through method overriding, we can modify super class method according to requirements of sub class.

Method Overriding in java is most useful features of java. Through inheritance we can reuse already existed code and through method overriding we can modify that reused code according to our requirements. This can be best explained with example.

class SuperClass{    void methodOfSuperClass()    {        System.out.println(“From Super Class”);    }}
class SubClass extends SuperClass{    void methodOfSuperClass()    {        //SuperClass method is overrided        //We can keep any tasks here according to our requirements.        System.out.println(“From Sub Class”);    }}
public class MethodOverriding{    public static void main(String[] args)    {        SuperClass superclass = new SuperClass();        superclass.methodOfSuperClass();         //Output : From Super Class        SubClass subclass = new SubClass();        subclass.methodOfSuperClass();          //Output : From Sub Class    }}

Let’s discuss rules to be followed while overriding a method.

  • Name of the overrided method must be same as in the super class. You can’t change name of the method in subclass.
  • Return Type Of Overrided Method :

The return type of the overrided method must be compatible with super class method. If super class method has primitive data type as its return type, then overrided method must have same return type in sub class also. If super class method has derived or user defined data type as its return type, then return type of sub class method must be of same type or its sub class. For example,

class SuperClass{    void firstMethodOfSuperClass()    {        System.out.println(“From Super Class”);    }
    double secondMethodOfSuperClass()    {        return 0.0;    }
    Object thirdMethodOfSuperClass()    {        return new Object();    }}
class SubClass extends SuperClass{    int firstMethodOfSuperClass()    {        //Compile time error, return type must be void not int    }
    void secondMethodOfSuperClass()    {        //Compile time error, return type must be double not void    }
    String thirdMethodOfSuperClass()    {        //No Compile time error,        //return type is compatible with super class method, because        //String is sub class of Object class        return new String();    }}

Visibility Of Overrided method:

You can keep same visibility or increase the visibility of overrided method but you can’t reduce the visibility of overrided methods in the subclass. For example, default method can be overided as default or protected or public method but not as private. For example,

class SuperClass{    protected void methodOfSuperClass()    {        System.out.println(“From Super Class”);    }}
class SubClass extends SuperClass{    private void methodOfSuperClass()    {        //Compile time error, can’t reduce visibility of overrided method        //here, visibility must be protected or public but not private or default    }}

Constructor chaining:

Constructor chaining is the process of calling one constructor from another constructor with respect to current object.

Constructor chaining can be done in two ways:

§  Within same class: It can be done using this() keyword for constructors in same class

§  From base class: by using super() keyword to call constructor from the base class.

Constructor chaining occurs through inheritance. A sub class constructor’s task is to

call super class’s constructor first. This ensures that creation of sub class’s object starts

with the initialization of the data members of the super class. There could be any

numbers of classes in inheritance chain. Every constructor calls up the chain till class at

the top is reached.

Why do we need constructor chaining ?

This process is used when we want to perform multiple tasks in a single constructor 

rather than creating a code for each task in a single constructor we create a separate

constructor for each task and make their chain which makes the program more

readable.

Constructor Chaining within same class using this() keyword :

Summary:

OOPs have following features:

1. Object             – Instance of Class2. Class               – Blue print of Object3. Encapsulation    – Protecting our Data4. Polymorphism   – Different behaviours at different instances5. Abstraction        – Hiding our irrelevant Data6. Inheritance        – One property of object is acquiring to another property of object