YuWebdesign



Java OOPS (Object Oriented Programming) Concept Interview Questions

By YuwebDesign

Object Oriented Programming features in Java

four pillars of oops

Java OOPs Interview Questions

OOPS is an acronym that stands for

  1. Object
  2. Oriented
  3. Programming
  4. Systems

Object-oriented programming is a programming model or approach
where the programs are organized around objects rather than logic and functions.

In other words, OOP mainly focuses on the objects that are required to be manipulated instead of logic.

This approach is ideal for the program with large and complex code that needs to be actively updated or maintained.

Java is not 100% Object-oriented because it makes use of eight primitive data types such as boolean, byte, char, int, float, double, long, short which are not objects.

Four Pillars of OOPs
  1. Inheritance
  2. Encapsulation
  3. Polymorphism
  4. Abstraction

Read more about OOPs concepts in Java >>>

Classes

A Class is an object constructor, a template/blueprint/definition/factory
for creating as many objects (or instances) as needed.

This blueprint includes all your data.

A class describes what an object knows and what an object does.

You can better visualize it as a human DNA – a definition of how something should be created when a program is running.

  1. All Java programming code is defined within a class. A Class has variables and methods.
  2. Variables are attributes which define the state of a class.
  3. Member variable, instance variable, and field are different words that mean the same thing. Field is the preferred term in Java.
  4. Methods define the behavior and are the place where the exact business logic has to be done. It contains a set of statements (or) instructions to satisfy the particular requirement.

Syntax of a class:

class Abc {
member variables // class body
methods}

Read moore about Classes in Java >>>

  1. Name of a class should be a noun
  2. starting with Capital letter: e.g., Car{}
  3. name of the java file should match the class name.

The contents of a class are called class members,
and these members can be methods or properties.

  1. Fields
  2. Methods
  3. Constructors
  4. Blocks
  5. Nested class and interface

Properties (variables, fields) store some value.

A Java field is a variable inside a class.
E.g, in a class representing an employee, the Employee class might contain the following fields:

  • name
  • position
  • salary
  • hiredDate

The corresponding Java class could be defined like this:

public class Employee {
  String  name     ;
  String  position ;
  int     salary   ;
  Date    hiredDate;
}
Declaring Class Fields in Java

Syntax:

[access_modifier] [static] [final] Type name [= initial value] ;
//only type and name are required.

Methods usually do something.


A method is like a function that is used to expose the behavior of an object.

Advantage of Method
  1. Code Reusability
  2. Code Optimization

The Java ClassLoader is a subset of JVM (Java Virtual Machine) that is responsible for loading the class files.

Whenever a Java program is executed it is first loaded by the classloader.

Java provides three built-in ClassLoaders:

  1. Bootstrap ClassLoader
  2. Extension ClassLoader
  3. System/Application ClassLoader


Methods

  1. You can pass data, known as parameters, into a method.
  2. Inside of a method we have statement(s)
  3. Methods define the actions that can be performed on classes.
    Sometimes they are also known as functions.
  4. Name of a method should be a verb
    that starts with a lowercase letter
    and describes best the action the method performs.
  5. Keep a method as short as possible.
    As a rule of thumb to up to 3 lines with 20 lines as a maximum.

Syntax:

method(parameters){
//method definition
}

A method is a block of code which only runs when it is called.

Inside main, call the myMethod() method:

public class MyClass {
static void myMethod() {
System.out.println("I just got executed!");
}

public static void main(String[] args) {
myMethod();
}
}

// Outputs "I just got executed!"

  1. Information can be passed to functions as a parameter inside the parentheses.
  2. You can add as many parameters as you want, separating them with a comma.
    Recommendation is however to use the least amount of parameters possible,
    with 3-5 parameters as a maximum.

E.g., method that takes a String called fname as parameter.
When the method is called, we pass along a first name,
which is used inside the method to print the full name:

public class MyClass {
static void myMethod(String fname) {
System.out.println(fname + " Refsnes");
}

public static void main(String[] args) {
myMethod("Liam");
myMethod("Jenny");
myMethod("Anja");
}
}
// Liam Refsnes
// Jenny Refsnes
// Anja Refsnes

A method uses parameters.
A caller passes arguments.

When we define a method, we give it parameters.
When we call a method, we give it arguments.

  1. Arguments are what you pass into methods.
    An argument (a value like 2, “Foo”, or a reference to a Dog) lands into a parameter.
    Arguments are a part of a calling of a method.
  2. A parameter is nothing more than a local variable that is going to store that data.
    A variable with a type and a name, that can be used inside the body of the method.
    Parameters are a part of definition of a method.

  1. static method can be accessed without creating an object of the class
  2. public can only be accessed by objects

public class MyClass {
static void myMethod() {
// code to be executed
}
}

  1. myMethod() – name of the method
  2. static means that the method belongs to the MyClass class
    and not an object of the MyClass class.
  3. void means that this method does not have a return value.

public class MyClass {
static int myMethod(int x, int y) {
return x + y;
}

public static void main(String[] args) {
System.out.println(myMethod(5, 3));
}
}
// Outputs 8 (5 + 3)

You can also store the result in a variable (recommended):

public class MyClass {
static int myMethod(int x, int y) {
return x + y;
}

public static void main(String[] args) {
int z = myMethod(5, 3);
System.out.println(z);
}
}
// Outputs 8 (5 + 3)

  1. The void keyword indicates
    that the method should not return a value.
  2. To return a value,
    a primitive data type (such as int, char, etc.) instead of void,
    and the return keyword inside the method should be used.

Objects have state and behavior, represented by instance variables and methods.

  1. Curry methods return a value but do not alter the state.
  2. Command methods alter the state but do not return a value.

Method signature is the method name and the number, type and order of its parameters.

Return types and thrown exceptions are not considered to be a part of the method signature.

A class cannot have two methods with same signature. If we try to declare two methods with same signature you will get a compile time error.

A method signature is the smallest type of a method.
Read more on type signature


Constructors

Instantiation of an Object is also known as construction.
  1. Constructor refers to a block of code which is used to initialize an object.
  2. Constructor looks like a method but it is in fact not a method.

    Objects are created from classes by subroutines called constructors,
    and destroyed by destructors.

    When a new object is created in a program a constructor gets invoked corresponding to the class.

  3. Constructor must have the same name as the class name.
  4. Constructor is automatically called when an object is created.
  5. All classes have constructors by default: if you do not create a class constructor yourself, Java creates one for you. However, then you are not able to set initial values for object attributes.
  6. Constructor has no return type as it does not return any value.
  7. There are two types of constructors: Default Constructor and Parameterized Constructor.
  8. Constructor can be overloaded.
    If the user created a constructor with a parameter then he should create another constructor explicitly without a parameter.
MyClass obj = new MyClass();

With “new MyClass()” (object allocation) we are calling
the default constructor of class myClass
to create a new object (or instance).

  1. Default Constructor:
    • If a user doesn’t create a constructor implicitly (no other constructor is defined by the user) a default constructor will be created.
    • Default constructor does not take any inputs/arguments.
    • Its main purpose is to initialize the instance variables with the default values.
    • Also, it is majorly used for object creation.
  2. Parameterized Constructor:
    • Parameterized constructor can take the arguments.
    • Parameterized constructor is capable of initializing the instance variables with the provided values.

  1. Constructors that take parameters are known as parametrized constructors.
  2. Constructor parameters are used to initialize attributes.
public class ConstructorExample {
   int age;
   String name;
	
   //Default constructor
   ConstructorExample(){
	this.name="Evergreen";
	this.age=16;
   }
	
   //Parameterized constructor
   ConstructorExample(String n,int a){
	this.name=n;
	this.age=a;
   }
   public static void main(String args[]){
	ConstructorExample obj1 = new ConstructorExample();
	ConstructorExample obj2 = 
		       new ConstructorExample("ForeverYoung", 99);
	System.out.println(obj1.name+" "+obj1.age);
	System.out.println(obj2.name+" "+obj2.age);
   }}

Output:

Evergreen 16
ForeverYoung 99

Copy Constructor in Java
  1. Copy constructor is a member function that is used to initialize an object using another object of the same class.
  2. Though there is no need for copy constructor in Java since all objects are passed by reference.
  3. Moreover, Java does not even support automatic pass-by-value.

  1. Constructor chaining is the process of calling one constructor from another with respect to the current object.
  2. Constructor chaining is possible only through legacy
    where a subclass constructor is responsible for invoking the superclass’ constructor first.
  3. There could be any number of classes in the constructor chain.

Constructor chaining can be achieved in two ways:

  1. Within the same class using this()
  2. From base class using super()

Singleton class is a class whose only one instance can be created at any given time, in one JVM.
A class can be made singleton by making its constructor private.

Objects

  1. Object is an instance of a class.

    A class is a template or blueprint from which objects are created.
    Object is an instance (result) of a class,
    and may be called a class instance or class object.

  2. An object is a real-world entity.
  3. Object is a runtime entity.
  4. An object has three characteristics:
    • State
    • Behavior
    • Identity
  5. An object is created using the ‘new’ keyword.
    ClassName obj = new ClassName();

    Whenever the JVM reads the “new()” keyword, it will create an instance of that class.

Read more about Objects in Java >>>

Class name (class is the data type) followed object name (or identifier) = keyword new followed by class name with parentheses (parentheses = constructor):

Type identifier = new Type constructor();

Or to better visualize:

ClassName objectName = new ClassName();

In OOP languages, words “object” and “instance” are used interchangeably,
because they are a representation of that class at a particular instant.


In practice, use the instance to say about one particular object,
and use an object to talk about many objects.

Object: Car
Attributes (or state or fields or values or variables): Color, Weight, Model
Methods (or behavior): Drive, Break, Accelerate, Slow Down, Gear change

Object: House
State: Address, Color, Area
Behavior: Open door, close door

class House {
   String address;
   String color;
   double area;
   void openDoor() {
      //code
   }
   void closeDoor() {
      //code
   }}

  1. States can be represented as instance variables (properties).
  2. Every object of same class can have different instance variable values.
    E.g., every house can have a different address, color etc.

  1. Behaviors can be represented as methods of the class.
  2. Every instance of a particular class has the same methods,
    but the methods can behave differently
    based on the value of the instance variables.

Object’s behavior acts on its state – that’s the whole point of an object.


In other words, methods use instance variable values.


E.g., “if dog is less than 14 pounds, make yippy sound, else…”
“increase weight by 5”
= change state.

  1. Object identity is typically implemented via a unique ID.
  2. The value of the ID is not visible to the external user.
  3. However, it is used internally by the JVM to identify each object uniquely.

Abstraction is a process where

  1. you show only “relevant” data
  2. and “hide” unnecessary details of an object from the user.

Read more about Abstraction OOPs concept >>>

Encapsulation binding object state (fields) and behavior (methods) together.

Read more about Encapsulation OOPs concept >>>

  1. A single object by itself may not be very useful.
    An application contains many objects.
  2. One object interacts with another object
    by invoking methods on that object.
    It is also referred to as Method Invocation.

Java OOPs Concepts Message Passing

Object Cloning in Java
  1. Object cloning in Java is the process of creating an exact copy of an object.
  2. It basically means the ability to create an object with a similar state as the original object.
  3. To achieve this, Java provides a method clone() to make use of this functionality.
  4. This method creates a new instance of the class of the current object and then initializes all its fields with the exact same contents of corresponding fields.
  5. To object clone(), the marker interface java.lang.Cloneable must be implemented to avoid any runtime exceptions.
  6. One thing you must note is Object clone() is a protected method, thus you need to override it.

Inheritance

Inheritance: process by which one class acquires all the properties and behaviors of another class.

  1. New classes are built upon existing classes (by reusing their code).
  2. The parent class is called the base class or super class.
  3. The child class is called the derived class or sub class.
  4. The child class extends the base class
    Extends keyword indicates that a new class derives from an existing class.
    The meaning of “extends” is to increase the functionality.
  5. The child class can reuse (inherits) methods and fields of the parent class.
  6. The child class can add new methods and fields to define only those features that are unique to it
  7. Inheritance is applicable for public and protected members only. Private members can’t be inherited.
Syntax of Java Inheritance
class Subclass extends Superclass  
{  
   //methods and fields  
}  

The keyword super in Java is a reference variable that refers the immediate parent class object.


With creation of the instance of subclass,
an instance of parent class is created implicitly
which is referred by super reference variable.

Usage of Java Keyword super
  1. to refer immediate parent class instance variable.


    If parent class and child class have same fields, property of the child class is used by default.
    The keyword super is used for accessing the parent property.


    E.g, for printing the common property color of the parent class Animal
    we need to use the keyword super,
    or color of current class will be used by default.

    class Animal{  
    String color="pink";  
    }  
    class Cat extends Animal{  
    String color="striped";  
    void printColor(){  
    System.out.println(color);//prints color of Cat class  
    System.out.println(super.color);//prints color of Animal class  
    }  
    }  
    class InstanceVariableSuper{  
    public static void main(String args[]){  
    Cat dog = new Cat();  
    dog.printColor();  
    }} 
    

    Output:

    striped
    pink
    
  2. to invoke immediate parent class method.


    It should be used if subclass contains the same method as parent class.
    In other words, it is used if method is overridden.

    class Animal{  
    void eat(){System.out.println("eating...");}  
    }  
    class Cat extends Animal{  
    void eat(){System.out.println("eating mouse");}  
    void purr(){System.out.println("purring");}  
    void sleep(){  
    super.eat();  
    purr();  
    }  
    }  
    class OverridenMethodSuper{  
    public static void main(String args[]){  
    Cat cat = new Cat();  
    cat.sleep();  
    }}  
    

    Output:

    eating...
    purring
    
  3. super() invokes immediate parent class constructor.
    class Animal{  
    Animal(){System.out.println("animal is created");}  
    } 
     
    class Cat extends Animal{  
    Cat(){  
    super();  
    System.out.println("cat is created");  
    }}
      
    class parentConstructorSuper{  
    public static void main(String args[]){  
    Cat cat = new Cat();  
    }}  
    

    Output:

    animal is created
    cat is created
    

IS-A relationship (Inheritance)

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

HAS-A relationship (Aggregation)
  1. If a class has an entity reference, it is known as aggregation.
  2. Relationship where one object contains other objects as a part of its state.
  3. Aggregation represents a HAS-A relationship.
  4. Aggregation represents the weak relationship between objects.

Benefits of Aggregation

  1. Aggregation is used for code reusability.
  2. Code reusability is best achieved by aggregation when there is no IS-A relationship.

Spouse.java

public class Spouse {  
String firstName, middleName, lastName;  
  
public Address(String city, String state, String country) {  
    this.firstName = firstName;  
    this.middleName = middleName;  
    this.lastName = lastName;  
} }  

Citizen.java

class Citizen{  
int ssn;  
String name;  
Spouse spouse;//Spouse is a class  

public Citizen(int ssn, String name, Spouse spouse){  
    this.ssn = ssn;  
    this.name = name;  
    this.spouse = spouse;  
}

void display(){  
System.out.println(ssn+" "+name);  
System.out.println(spouse.firstName+" "+spouse.middleName+" "+spouse.lastName);  
}  

public static void main(String[] args){  
Spouse spouse1 = new Spouse("Thais","Venera","Roman");  
Spouse spouse2 = new Spouse("Esphir","Ishtar","Greek");  
  
Citizen citizen1 = new Citizen(111,"Jupiter Roman", spouse1);  
Citizen citizen2 = new Citizen(777,"Apollo Greek", spouse2);  
      
citizen1.display();  
citizen2.display();  
}}  

Output:

111 Jupiter Roman
Thais  Venera Roman

777 Apollo Greek
Esphir Ishtar Greek

Citizen has an entity reference spouse, so relationship is Citizen HAS-A spouse.

IS-A relationship (Inheritance) vs HAS-A relationship (Aggregation)

Inheritance should be used only if the relationship IS-A is maintained throughout the lifetime of the objects involved; otherwise, aggregation is the best choice.

Association is a relationship between two separate classes which establishes through their Objects.
In simple words, Association represents the relationship between the objects.

In OOPs, an Object communicates to other Object to use functionality and services provided by that object.

  • Objects have their own lifecycle and there is no owner.
  • One object can be associated with one object or many objects.
    The relationships can be one to one, one to many, many to one and many to many.
  • Association can be uni-directional (department can have students but vice versa is not possible) or bi-directional.
Four types of association between the objects:
  1. One to One (e.g. husband and wife)
  2. One to Many (e.g., one mother and many children)
  3. Many to One (e.g., many children and one father)
  4. Many to Many (e.g., many cousins to many cousins)

E.g., Teacher and Student.
Multiple students can associate with a single teacher
and a single student can associate with multiple teachers
but there is no ownership between the objects and both have their own lifecycle.

An aggregation is a special form of Association where:

  • It represents Has-A relationship
  • all objects have their own lifecycle but there is ownership
    and child object can not belong to another parent object.
  • It is a unidirectional association i.e. a one way relationship.
    E.g., department can have students but vice versa is not possible and thus unidirectional in nature.
  • In Aggregation, both entities can survive individually
    which means ending one entity will not effect the other entity.
  • E.g., University has Departments.
    University class references object(s) of the Department class = it is associated with Department class through its Object(s).
    Departments have Students.
    Department class references object(s) of Student class = it is associated with Student class through its Object(s).

    When do we use Aggregation?
    Code reuse is best achieved by aggregation.

    Composition is a specialized restricted strong form of Aggregation in which two entities are highly dependent on each other.

    1. It represents part-of relationship.
    2. In composition, both the entities are dependent on each other.
    3. We can call this as a “death” relationship: when there is a composition between two entities, the composed object cannot exist without the other entity.

    E.g., Human – Heart
    1) Human cannot survive without Heart.
    2) Heart alone does not have any significance.
    3) When human created, heart is created and human dies, heart also dies.
    4) Human – Heart has one-to-one mapping, also heart is not shareable with other human.

    E.g., House – Rooms
    House can contain multiple rooms.
    There is no independent life of room.
    Any room can not belongs to two different houses.
    If we delete the house, room will automatically delete.

    Aggregation Composition
    Dependency Child can exist independently of Parent.
    An object borrowed from someone else.

    E.g., University-Department-Student: delete Department and Student still exist in the University.

    Object lifetime depends on its owner.
    The child cannot exist independent of the parent.
    Contained object is composed inside containing object,
    when the containing object dies, the memory for contained object is also reclaimed.

    E.g.: Human Heart, Heart dies with Human.

    Type of Relationship “has-a” relation. “part-of” relation
    Type of Association Weak Association Strong Association

    1. Association (has-a)
      Association –> A has-a B object (as a member variable)
      An association almost always implies that one object has the other object as a field/property/attribute (terminology differs).

      It means there is almost always a link between objects (they are associated).

      Order object has a Customer object

      public class Order {
          private Customer customer
      }
      
    2. Dependency (references)

      Dependency –> A references B (as a method parameter or return type)

      A dependency typically (but not always) implies that an object accepts another object as a method parameter, instantiates, or uses another object.

      It means there is no conceptual link between two objects.
      e.g. EnrollmentService object references Student & Course objects (as method parameters or return types)

      public class EnrollmentService {
          public void enroll(Student s, Course c){}
      }
      
      public class A {
          private C c;
          public void myMethod(B b) {
              b.callMethod();
          }
      }
      
    3. Aggregation (has-a + whole-part)
      Special kind of association where there is whole-part relation between two objects. they might live without each other though.

      public class PlayList{
          private List songs;
      }
      

      Note: the trickiest part is to distinguish aggregation from normal association. Honestly, I think this is open to different interpretations.

    4. Composition (has-a + whole-part + ownership)
      Special kind of aggregation. An Apartment is composed of some Rooms. A Room cannot exist without an Apartment. when an apartment is deleted, all associated rooms are deleted as well.

      public class Apartment{
          private Room bedroom;
          public Apartment() {
             bedroom = new Room();
          }
      }
      

    • Method Overriding (so that Runtime Polymorphism can be achieved).
    • Code Reusability.

    Six Types of Inheritance are supported in OOPs (1S2H3M)
    1. Single Inheritance
      a single class extends another class (A->B).
      Supported in Java.

      OOPs Inheritance Types: Single Inheritance

    2. Multi-level inheritance
      • Class extends the child class of the base class (A->B->C).
      • Supported in Java.

      OOPs Inheritance Types: Multilevel Inheritance

    3. Hierarchical inheritance
      • More than one classes extends the same class.
      • One Parent has many Children who also may have several Children.

        e.g., Both class B and Class C extend class A (A->B and A->C).

      • Supported in Java.

      OOPs Inheritance Types: Hierarchical Inheritance

    4. Multiple Inheritance
      • one class extends more than one classes,
        a child class has two parent classes (A->C and B->C).
      • Java doesn’t support multiple inheritance and renders a compile-time error if you inherit 2 classes.
      • For Java supporting Multiple Inheritance means managing Child class dependency of more than one Parent.

        The problem with multiple inheritance is that if multiple parent classes have the same method name,
        then at runtime it becomes difficult for the compiler to decide which parent method to execute from the child class.

        The problem is commonly referred to as Diamond Problem.

      • Multiple Inheritance is very rarely used in software projects.
      • It often leads to problems in the hierarchy and results in unwanted complexity when further extending the class.
      • However, Multiple Inheritance in Java can be achieved using Interfaces.

      OOPs Inheritance Types: Multiple Inheritance

    5. Multipath inheritance
    6. a child class has the same base class with its parents (A->B->D, A->C->D, A->D).

      OOPs Inheritance Types: Multipath Inheritance

    7. Hybrid Inheritance
      a combination of more than one inheritance types.

      E.g., Hybrid Inheritance as the combination of both Single and Multiple Inheritance is not directly supported in Java, but can be achieved through interface.
      OOPs Inheritance Types: Hybrid Inheritance

    Only One Superclass

    Except Object class, which has no superclass, every class has one and only one direct superclass (single inheritance).

    A superclass can have any number of subclasses.
    But a subclass can have only one superclass.

    This is because Java does not support multiple inheritance with classes.

    Although with interfaces, multiple inheritance can be achieved in Java.

    Default Superclass

    In the absence of any other explicit superclass, every class is implicitly a subclass of Object class.

    Inheriting Constructors

    A subclass inherits all the members (fields, methods, and nested classes) from its superclass.

    Constructors are not members, so they are not inherited by subclasses,
    but the constructor of the superclass can be invoked from the subclass.

    Private member inheritance

    A subclass does not inherit the private members of its parent class.
    However, if the superclass has public or protected methods(like getters and setters) for accessing its private fields, these can also be used by the subclass.

    In sub-classes we can inherit members as is, replace them, hide them, or supplement them with new members:

    • The inherited fields can be used directly, just like any other fields.
    • We can declare new fields in the subclass that are not in the superclass.
    • The inherited methods can be used directly as they are.
    • We can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it (as in example above, toString() method is overridden).
    • We can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.
    • We can declare new methods in the subclass that are not in the superclass.
    • We can write a subclass constructor that invokes the constructor of the superclass, either implicitly or by using the keyword super.

    Encapsulation

    Java OOPs Concepts Encapsulation

    1. Encapsulation – in Java is a mechanism of binding/wrapping up the code(methods) and data(variables) together into a single unit(capsule).
    2. Encapsulation hides details from outside world at the implementation level:
      internal working is hidden and can be changed later without impacting outside clients.

    E.g., User should be able to login to their bank online with their user_id and password.
    After entering user_id, password they expect to login,
    what happens when they press login, how the input data is sent to the server,
    and how it gets verified is all abstracted away from the user.

    Because of Encapsulation, you can change the internal implementation of the login with ease without impacting clients who are using this feature.

    1. Code maintainability.
    2. Flexibility: implementation details of the class can be changed
      without affecting the classes that are using it.
    3. Increased security of data: protects the code from others.
      The data is hidden from the outer world and can be accessed only via current class methods.
      This helps in protecting the data from any unnecessary modification.
    4. Better control of class attributes and methods.
      Class variables can be made read-only (if you omit the set method),
      or write-only (if you omit the get method)

    How to

    1. Declare the instance variables as private
      (accessible only within the same class,
      an outside class has no direct access to it).

      You can only set and get values of these variables
      through the methods of the class.

    2. Have getter and setter methods in the class
      to set and get the values of the variables.
      This will force others to call the setters rather than access the data directly.

    Private variables can be accessed with public getter and setter methods.

    The get method returns the variable value, and the set method sets the value.

    Syntax for both is that they start with either get or set, followed by the name of the variable, with the first letter in upper case:

    public class Person {
      private String name; // private = restricted access
    
      // Getter
      public String getName() {
        return name;
      }
    
      // Setter
      public void setName(String newName) {
        this.name = newName;
      }
    }
    
      public static void main(String[] args) {
        Person myObj = new Person();
    
        myObj.name = "John";  // error
        System.out.println(myObj.name); // error  
    
        myObj.setName("John"); // Set the value of the name variable to "John"
        System.out.println(myObj.getName()); //John
    }
    

    Abstraction

    1. Abstraction deals with (conceptual, abstract) ideas rather than (specific, concrete) events.
      Abstraction hides complexity by giving you a more abstract picture.
    2. Abstraction is the methodology of hiding the implementation details from the user and revealing only the functionality to them.
    3. Abstraction hides details at the design level: it lets you focus on what the object does instead of how it does it.

    E.g., vehicle can move.
    User won’t know how (if it will drive, or fly or sell). The most essential thing is the ability to move without focusing on details of how exactly will the spatial position of the Vehicle object will be changed.

    There are different levels of Abstraction.

    Abstraction can be achieved in two ways:

    1. Abstract Classes (0-100% of abstraction can be achieved)
    2. Interfaces (100% of abstraction can be achieved)

    As the level of Abstraction increases, things start getting simpler and simpler because the details are left out.

    It is a good practice that classes should interact with other classes with the same or higher level of abstraction.


    Abstract Classes and Interfaces

    We can create the Abstract class by using “Abstract” keyword before the class name. An abstract class can have both “Abstract” methods and “Non-abstract” methods that are a concrete class.

    Abstract method

    The method which has only the declaration and not the implementation is called the abstract method and it has the keyword called “abstract”. Declarations are the ends with a semicolon.

    Non-abstract method

    An abstract class may have a non-abstract method also.
    The concrete Subclass which extends the Abstract class should provide the implementation for abstract methods.

    1. An interface is a template/blueprint of a class, which has only method declarations and not the method implementation.
    2. It is a collection of abstract methods and static constants.
      In an interface, each method is public and abstract but it does not contain any constructor.
      Thus, interface basically is a group of related methods with empty bodies.
    3. Multiple inheritance cannot be achieved in Java.
      However, Interface concept can be used to overcome this problem.
    public interface Animal {
      public void eat();
      public void sleep();
      public void run();
    }
    

    In Java, we use Abstract Class and Interface to achieve Abstraction.

    Java OOPs Concepts Abstract Class vs Interface

    Abstract Class Interface
    Code Can provide complete, default code
    and/or just the details that have to be overridden
    Cannot provide any code at all, just the signature
    Abstract Class contains instance variables. The interface contains only constants.
    Methods Contains Abstract methods as well as Non-Abstract methods. All methods of an Interface are abstract.
    Inheritance A class may extend only one abstract class A Class may implement several interfaces
    Subclass Method Implementation The class which extends the Abstract class shouldn’t require implementing all the methods, only Abstract methods need to be implemented in the concrete sub-class. Classes which implement the interface should provide the implementation for all the methods.
    Adding new Method If we add a new method to an abstract class then we have the option of providing default implementation and therefore all the existing code might work properly If we add a new method to an Interface then we have to track down all the implementations of the interface and define implementation for the new method
    Constructor Can contain constructors.
    Abstract classes have a default constructor and it is called whenever the concrete subclass is instantiated.
    Cannot contain constructors.
    Cannot be instantiated.
    Performance Fast Slow as it needs to find the corresponding method in the actual class

    Marker Interface

    A Marker interface can be defined as the interface having no data member and member functions.
    In simpler terms, an empty interface is called the Marker interface.
    The most common examples of Marker interface in Java are Serializable, Cloneable etc.
    The marker interface can be declared as follows.

    public interface Serializable{
    }
    

    Polymorphism

    1. Polymorphism comes from the Greek roots “poly” (many) and “morphe” (form).
    2. Polymorphism can be described as “one interface, many implementations”.
    3. Polymorphism is a characteristic of being able to assign a different meaning or usage to something in different contexts
    4. It is is the ability that allows an entity (such as a variable, a function, or an object)
      to take multiple forms.
    5. A single object can refer the super class or sub-class depending on the reference type.

      Read more about Polymorphism in Java >>>

    6. Run-time Polymorphism is applicable for overriding and Compile-time Polymorphism for overloading.

      Read more about Method Overriding in Java >>>

      Read more about Method Overloading in Java >>>

    Polymorphism is based on on inheritance and occurs when many classes are related to each other by inheritance.

    Inheritance lets us inherit attributes and methods from another class.
    Polymorphism uses those methods to perform a single action in different ways.

    For example, lets say we have a class Animal that has a method animalSound(),
    here we cannot give implementation to this method as we do not know
    which class would extend Animal class.
    So, we make this method abstract like this:

    public abstract class Animal{
       ...
       public abstract void animalSound();
    }

    Animal class Lion that extends Animal class
    can provide implementation details.

    public class Lion extends Animal{
    ...
        @Override
        public void animalSound(){
            System.out.println("Roar");
        }
    }

    Read more about Java Polymorphism on Oracle website >>>

    In Computer Science, there are the following types of polymorphism:

    1. Ad-hoc polymorphism, also called Static Polymorphism or Compile-time Polymorphism or Method Overloading

      allows methods having same name to act differently for different types.

      the compiler (or the runtime system, depending on whether overloading resolution is static or dynamic)
      chooses an appropriate implementation for each application of the function,
      based on the types of the arguments.

      E.g., the + operator adds two integers and concatenates two strings.

      If you overload a static method in Java, it is the example of compile time polymorphism.

    2. Inclusion Polymorphism, also called Subtyping or Dynamic Polymorphism or Run-time Polymorphism or Dynamic Method Dispatch or Method Overriding

      A call to an overridden method is resolved at run-time rather than compile-time.

      It is the ability to use derived classes through base class pointers and references.

      The address of the method is not located by the Compiler at compile-time,
      rather, the right pointer from the virtual table is dereferenced to invoke the method at run-time.

      The concept of Virtual Function, also known as Dynamic Linkage, is employed to achieve Inclusion Polymorphism.
      The usage of Virtual Function allows the selection of that function which is to be invoked based on the kind of object for which it is called.

    3. Coersion Polymorphism, also called Casting
      Coersion Polymorphism occurs when an object or primitive is cast into some other type.

      It could be either Implicit or Explicit.

      Implicit casting happens as a responsibility of Compiler itself.
      E.g., float f=100 (integer implicitly gets promoted to float)

      Read more about Type Casting in Java>>>

    4. Parametric polymorphism also called Early Binding
      Parametric Polymorphism opens a way to use the same piece of code for different types.

      a method or a data type can be written generically
      so that it can handle values identically
      without depending on their type.

      It uses variables in place of actual types,
      and then instantiates with particular types as needed.

      Parametric definitions are uniform: all of their instances behave the same.

      Parametric polymorphism in Java generally refers to Generics/Templates.
      Using Templates, the same function can be parameterized with different types of data,
      but this needs to be decided at compile-time itself, and hence, this polymorphism is named so.

      template  
      temp greater(temp a, temp b) { 
          if (a > b) 
              return a; 
          else
              return b; 
      

      This program can find greater of two Integers or two Strings.

      If we wish to achieve such polymorphism for pointers, it turns into Ad-hoc Polymorphism.

    1. Use:
      • Method overloading is used to increase the readability of the program.
      • Method overriding is used to provide the specific implementation of its super class method.
    2. Where occurs:
      • Method overloading is performed within child class.
      • Method overriding occurs in two classes with IS-A (inheritance) relationship.
    3. Parameters:
      • Method overloading: parameter must be different.
      • Method overriding: parameter must be same.
    4. Polymorphism type
      • Method overloading is the example of compile-time polymorphism (static binding) .
      • Method overriding is the example of run-time polymorphism (dynamic binding).
    5. Method return type:
      • Method overloading can’t be performed by changing return type of the method only.
        Return type can be same or different in method overloading.
        But you must have to change the parameter.
      • Method overriding: return type must be same or covariant.


    Overriding

    Dynamic/Run-time Polymorphism or Dynamic Method Dispatch or Method Overriding or Late Binding

    Method overriding happens if the sub class method satisfies the below conditions with the Super class method:

    1. Method name should be the same
    2. Argument should be the same
    3. Return type should be the same

    The key benefit of overriding is that the Sub class can provide some specific information about that sub class type while extending the super class.

    1. Rule 1: There must be an IS-A relationship (inheritance).
    2. Rule 2: A subclass (child class) must have the same method name as the parent class (superclass).
    3. Method overriding is used by the child class to provide the specific implementation of the method that has been declared by a parent class.
    4. Rule 3: The child method must have the same parameters as the parent methods.
    5. Method overriding is used for runtime polymorphism: a call to an overridden method is resolved at run-time rather than compile-time.
    6. An overridden method is called through the reference variable of a superclass.
    7. The determination of the method to be called is based on the object being referred to by the reference variable.
    Java Runtime Polymorphism Examples

    Java Runtime Polymorphism Example: Shape

    class Shape{  
    void draw(){System.out.println("drawing...");}  
    }  
    class Square extends Shape{  
    void draw(){System.out.println("drawing square");}  
    }  
    class Circle extends Shape{  
    void draw(){System.out.println("drawing circle");}  
    }  
    class Triangle extends Shape{  
    void draw(){System.out.println("drawing triangle");}  
    }  
    class TestPolymorphism2{  
    public static void main(String args[]){  
    Shape s;  
    s=new Rectangle();  
    s.draw();  
    s=new Circle();  
    s.draw();  
    s=new Triangle();  
    s.draw();  
    } } 
    

    Output:

    drawing square
    drawing circle
    drawing triangle
    

    Java Runtime Polymorphism Example: Animal

    class Animal{  
    void eat(){System.out.println("eating...");}  
    }  
    class Dog extends Animal{  
    void eat(){System.out.println("eating bone");}  
    }  
    class Cat extends Animal{  
    void eat(){System.out.println("eating mouse");}  
    }  
    class Lion extends Animal{  
    void eat(){System.out.println("eating prey");}  
    }  
    class TestPolymorphism3{  
    public static void main(String[] args){  
    Animal a;  
    a=new Dog();  
    a.eat();  
    a=new Cat();  
    a.eat();  
    a = new Lion();  
    a.eat();  
    }}  
    

    Output:

    eating bone
    eating mouse
    eating prey
    

    Java Runtime Polymorphism with Multilevel Inheritance
    class Animal{  
    void eat(){System.out.println("eating...");}  
    }  
    class Lion extends Animal{  
    void eat(){System.out.println("eating prey");}  
    }  
    class BabyLion extends Dog{  
    void eat(){System.out.println("drinking milk");}  
    public static void main(String args[]){  
    Animal a1,a2,a3;  
    a1 = new Animal();  
    a2 = new Lion();  
    a3 = new BabyLion();  
    a1.eat();  
    a2.eat();  
    a3.eat();  
    }}  
    

    Output:

    eating...
    eating prey
    drinking milk
    

    Upcasting

    Upcasting: reference variable of Parent class refers to the object of Child class.

    class Parent {}  
    class Child extends Parent {} 
    
    Parent obj = new Child();//upcasting  
    

    Reference variable of class type or an interface type can be used.

    interface Interface {}  
    class Parent {}  
    class Child extends Parent implements Interface {}  
    

    Here, the relationship of Child class would be:

    1. Child IS-A Parent
    2. Child IS-A Interface
    3. Child IS-A Object

    Object is the root class of all classes in Java, so we can write Child IS-A Object.

    class Animal{  
      void run(){System.out.println("Running");}  
    }  
    class Cheetah extends Animal{  
      void run(){System.out.println("Running as fast as 75km/h");}  
      
      public static void main(String args[]){  
        Animal myCheetah = new Cheetah();//upcasting  
        b.run();  
      }  
    } 
    

    Output:

    Running as fast as 75km/h
    
    1. Cheetah class extends Animal class and overrides its run() method.
    2. run method is called by the reference variable of Parent class.
    3. It refers to the Subclass object and Subclass method overrides the Parent class method,
      so the subclass method is invoked at runtime.
    4. Since method invocation is determined by the JVM not compiler, it is known as runtime polymorphism.

    Covariant Return Type in Method Overriding
    1. A subclass overrides a method whose return type is Non-Primitive
    2. A subclass overrides a method by changing its return type to subclass type.
    class A{  
    A get(){return this;}  
    }  
      
    class B1 extends A{  
    B1 get(){return this;}  
    void message(){System.out.println("welcome to covariant return type");}  
      
    public static void main(String args[]){  
    new B1().get().message();  
    } }
    

    Output:

    welcome to covariant return type
    

    Java Runtime Polymorphism can’t be achieved by Data Members

    A method is overridden, not the data members.

    class Cheetah {  
     int speedLimit = 75;  
    }  
    class Rocket extends Cheetah {  
     int speedLimit = 17600;  
      
     public static void main(String args[]){  
      Cheetah obj = new Rocket();  
      System.out.println(obj.speedLimit); 
    }  
    
    1. Both the classes have a data member speedLimit.
    2. Data member is accessed by the reference variable of Parent class, which refers to the subclass object.
    3. Data member is not overridden, so data member of the Parent class will be accessed.

    Output:

    75
    

    Java main method cannot be overridden

    We cannot override Java main method
    because main is a static method.

    Watch this

    You cannot override a private method in Subclass
    because it’s not accessible there.

    What you can do is create another private method with the same name in the child class:

    class Base {
    private static void display() {
    System.out.println("Static or class method from Base");
    }
    public void print() {
    System.out.println("Non-static or instance method from Base");
    }
    class Derived extends Base {
    private static void display() {
    System.out.println("Static or class method from Derived");
    }
    public void print() {
    System.out.println("Non-static or instance method from Derived");
    }
    public class test {
    public static void main(String args[])
    {
    Base obj= new Derived();
    obj1.display();
    obj1.print();
    }
    }
    

    A static method cannot be overridden

    Static methods cannot be overridden
    because they are not dispatched on the object instance at run time.
    The compiler decides which method gets called.

    1. Static method is bound with class
      whereas instance method is bound with an object.
    2. Stack Memory in Java is used for static memory allocation, and an instance belongs to the heap area.

    If you create a similar Method within the Child Class
    with the same return type and same method arguments
    then it will hide the Super Class Method;
    this is known as Method Hiding.


    Overloading

    Static/Compile-time Polymorphism or Method Overloading or Early Binding

    Method overloading happens for different classes or within the same class.

    For method overloading,
    subclass method should satisfy the below conditions
    with the Super class method (or) methods in the same class itself:

    class has multiple methods having

    1. Same method name
    2. Different in parameters (argument type or number)
    3. May have different return types

    Advantage of method overloading:
    having the same name of the methods increases the readability of the program.

    Compile-time Polymorphism:
    overloading of a a static method in Java.

    Two ways to overload the method in Java
    1. Changing number of arguments
      class AddNumbers{  
      static int add(int a,int b){return a+b;}  
      static int add(int a,int b,int c){return a+b+c;}  
      }  
      class OverloadingArgumentQuantity{  
      public static void main(String[] args){  
      System.out.println(AddNumbers.add(1,1));  
      System.out.println(AddNumbers.add(1,1,1));  
      }}  
      

      Output:

      2
      3
      
      • first add() method performs addition of two numbers
      • second add method performs addition of three numbers.
      • static methods provide no need to create instance for calling methods.
    2. Changing the data type of arguments
      class AddNumbers{  
      static int add(int a, int b){return a+b;}  
      static double add(double a, double b){return a+b;}  
      }  
      class OverloadingArgumentDatatype{  
      public static void main(String[] args){  
      System.out.println(AddNumbers.add(1,1));  
      System.out.println(AddNumbers.add(1.1,1.2)); 
      }} 
      

      Output:

      2
      2.3
      

    Constructor Overloading in Java

    In Java, constructor overloading is a technique of adding any number of constructors to a class each having a different parameter list. The compiler uses the number of parameters and their types in the list to differentiate the overloaded constructors.

    class Demo {
    int i;
    public Demo(int a) {
      i=k;
    }
    public Demo(int a, int b){
    //body
    }
    }
    

    Method Overloading by changing the return type of the method – not possible in Java
    1. In java, Method Overloading is not possible by changing the return type of the method because of ambiguity.
    2. Compile Time Error is better than Run Time Error. So, java compiler renders compiler time error if you declare the same method having same parameters.
    class AddNumbers{  
    static int add(int a, int b){return a+b;}  
    static double add(int a, int b){return a+b;}  
    }  
    class OverloadingMethodDatatype{  
    public static void main(String[] args){  
    System.out.println(AddNumbers.add(1, 1));////ambiguity  
    }} 
    

    Output:

    Compile Time Error: method add(int,int) is already defined in class AddNumbers
    

    Java can not determine which sum() method should be called.

    Overloading Java main() Method
    1. You can have any number of main methods in a class by method overloading.
    2. But JVM calls main() method which receives string array as arguments only.
    class OverloadingMainMethod{  
    public static void main(String[] args){System.out.println("main with String[]");}  
    public static void main(String args){System.out.println("main with String");}  
    public static void main(){System.out.println("main without args");}  
    }  
    

    Output:

    main with String[]
    

    Watch this

    Method Overloading and Type Casting

    One type is promoted to another implicitly if no matching datatype is found.
    Read more about Java Type Casting >>>

    Example of Method Overloading with Type Promotion if matching found
    If there are matching type arguments in the method, type promotion is not performed.

    class OverloadingWithTypeCasting{  
      void sum(int a,int b){System.out.println("int arg method invoked");}  
      void sum(long a,long b){System.out.println("long arg method invoked");}  
      
      public static void main(String args[]){  
      OverloadingWithTypeCasting obj = new OverloadingWithTypeCasting();  
      obj.sum(20,20);//now int arg sum() method gets invoked  
      } }  
    

    Output:

    int arg method invoked
    

    Method Overloading with Type Promotion in case of ambiguity

    1. If there are no matching type arguments in the method, and each method promotes similar number of arguments, there will be ambiguity.
    2. One type is not de-promoted implicitly for example double cannot be depromoted to any type implicitly.
    class OverloadingWithTypeCastingAmbiguity{  
      void sum(int a,long b){System.out.println("a method invoked");}  
      void sum(long a,int b){System.out.println("b method invoked");}  
      
      public static void main(String args[]){  
      OverloadingWithTypeCastingAmbiguity obj = new OverloadingWithTypeCastingAmbiguity();  
      obj.sum(20,20); //ambiguity  
    }}  
    

    Output:

    Compile Time Error
    


    Leave a Reply or Comment

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