03 OOPS - Inheritance & Polymorphism
03 OOPS - Inheritance & Polymorphism
What is Polymorphism?
Subtyping
Method Overloading
Method Overriding
Advantages of Polymorphism
Problems with Polymorphism
Reading List
When you add the static keyword to a variable, it means that the variable is no longer
tied to an instance of the class. This means that only one instance of that static
member is created which is shared across all instances of the class. Static variables
are stored in heap memory just like non-static variables. The difference is that
static variables are stored in a separate static segment of the heap memory.
System.out.println(StaticExample.myStaticVariable);
Static methods are accessed using the class name and the dot operator. You don’t need
to create an instance of the class to access the static method.
StaticExample.myStaticMethod();
Static methods can only access static variables and other static methods. They can not
access non-static variables and methods by default. If you try to access a non-static
variable or method from a static method, the compiler will throw an error.
Inheritance
Inheritance is the mechanism that allows one class to acquire all the properties from
another class by inheriting the class. We call the inheriting class a child class and
the inherited class as the superclass or parent class.
The idea behind inheritance in Java is that you can create new classes that are built
upon existing classes. When you inherit from an existing class, you can reuse methods
and fields of the parent class. Moreover, you can add new methods and fields in your
current class also.
Imagine, as a car manufacturer, you offer multiple car models to your customers. Even
though different car models might offer different features like a sunroof or
bulletproof windows, they would all include common components and features, like
engine and wheels.
It makes sense to create a basic design and extend it to create their specialized
versions, rather than designing each car model separately, from scratch.
Similarly, with inheritance, we can create a class with basic features and behavior
and create its specialized versions, by creating classes, that inherit this base
class. In the same way, interfaces can extend existing interfaces.
Let us create a new class User which should be the parent class of Student :
Now, let us create a new class Student which should be the child class of User . Let
us add some methods specific to the student class:
...
}
Now in order to inherit the methods and fields of the parent class, we need to use the
keyword extends :
...
}
To pass the values to the parent class, we need to create a constructor and use the
keyword super :
Types of inheritance
There are four types of inheritance:
Single - A single inheritance is when a class can have only one parent class.
Multilevel - A multilevel inheritance is when a class can have multiple parent
classes at different levels.
Hierarchical - When two or more classes inherits a single class, it is known
as hierarchical inheritance.
Multiple - When a class can have multiple parent classes, it is known as
multiple inheritance.
Diamond problem
What is Polymorphism?
Polymorphism is one of the main aspects of Object-Oriented Programming(OOP). The word
polymorphism can be broken down into “Poly” and “morphs”, as “Poly” means many and
“Morphs” means forms. In simple words, we can say that ability of a message to be
represented in many forms.
Polymorphism in Java can be achieved in two ways i.e., method overloading and method
overriding.
Compile-time polymorphism
Runtime polymorphism
Subtyping
Subtyping is a concept in object-oriented programming that allows a variable of a base
class to reference a derived class object. This is called polymorphism, because the
variable can take on many forms. The variable can be used to call methods that are
defined in the base class, but the actual implementation of the method is defined in
the derived class.
The Student class inherits the name and email properties from the User class. The
Student class also has its own properties batchName and psp. The Student class can be
used in place of the User class, because the Student class is a subtype of the User
class. The following is an example of how this works:
The advantage of sub-typing is that if you have a method that can accept any kind of
User - then you can easily pass User or any of its subtypes while calling that method.
This concept is heavily used in the Collections Framework.
class Main(){
public void makePayment(User u){
...
}
public static void Main(){
User u = new User();
Student s = new User();
makePayment(u);
makePayment(s);
}
}
Method Overloading
Method overloading is a feature that allows a class to have more than one method
having the same name, if their argument lists are different. It is similar to
constructor overloading in Java, that allows a class to have more than one constructor
having different argument lists.
Let's take an example of a class that has two methods having the same name but
different in parameters.
In the above example, the class has two methods with the same name printUser but
different in parameters. The first method has no parameters, and the second method has
two parameters. This is called method overloading.
The compiler distinguishes these two methods by the number of parameters in the list
and their data types. The return type of the method does not matter.
Method Overriding
Runtime polymorphism is also called Dynamic method dispatch. Instead of resolving the
overridden method at compile-time, it is resolved at runtime.
Here, an overridden child class method is called through its parent's reference. Then
the method is evoked according to the type of object. In runtime, JVM figures out the
object type and the method belonging to that object.
Runtime polymorphism in Java occurs when we have two or more classes, and all are
interrelated through inheritance. To achieve runtime polymorphism, we must build an
"IS-A" relationship between classes and override a method.
If a child class has a method as its parent class, it is called method overriding.
If the derived class has a specific implementation of the method that has been
declared in its parent class is known as method overriding.
@Override
public void printUser() {
System.out.println("Name: " + name + ", Email: " + email + ", Batch: " +
batchName + ", PSP: " + psp);
}
}
In the above example, we have added a method to the Student class that overrides the
method in the User class. The Student class has a method with the same name and
parameters as the User class. The Student class method has an additional print
statement that prints the batchName and psp properties.
The @Override annotation is optional, but it is a good practice to use it. It is used
to ensure that the method is actually being overridden. If the method is not being
overridden, the compiler will throw an error.
Advantages of Polymorphism
Code reusability is the main advantage of polymorphism; once a class is
defined, it can be used multiple times to create an object.
In compile-time polymorphism, the readability of code increases, as nearly
similar functions can have the same name, so it becomes easy to understand the
functions.
The same method can be created in the child class as in the parent class in
runtime polymorphism.
Easy to debug the code. You might have intermediate results stored in arbitrary
memory locations while executing code, which might get misused by other parts
of the program. Polymorphism adds necessary structure and regularity to
computation, so it is easier to debug.
Reading List
Deadly Diamond of Death
Detailed explanation of the diamond problem
Duck Typing
OOP in Python