Polymorphism means having many forms. The word “poly” means many and “morphs” means forms. In java, it is a concept that allows the user to perform a single action in different ways.
Take a real-life example: Consider a man and at the same time he can be a father, a husband, an employee that is he is having a different character and posses different behavior in different situations. Similarly, a class in a program has a method and the subclass have the same method but with a different task to perform related to the first method. This is called polymorphism.
In Java polymorphism is mainly divided into two types:
Compile-time Polymorphism or Static Polymorphism.
Runtime Polymorphism or Dynamic Polymorphism.
1. Compile-time Polymorphism:
It is also known as static polymorphism. In this type of program, the flow of control is decided at compile time itself and if any error is found, they are resolved at compile time. This can be achieved by method overloading.
Method Overloading:
Method Overloading allows the user to have more than one method that has the same name, they are differed by the number of the parameter lists, sequence, and data types of parameters.
Example: With a number of arguments
class ExampleTest
{
int add(int x, int y)
{
return x + y;
}
int add(int x, int y, int z)
{
return x + y + z;
}
}
public class Main
{
public static void main(String args[])
{
ExampleTest obj = new ExampleTest();
System.out.println(obj.add(50, 30));
System.out.println(obj.add(20, 10, 20));
}
}
Output:
80 50
2. Runtime Polymorphism:
It is also known as Dynamic Method Dispatch. It is a process in which a call to an overridden method is resolved at runtime. This type of polymorphism is achieved by Method Overriding.
Method Overriding:
Method Overriding is a feature that allows the user to declare a method with the same name in a sub-class that is already present in a parent class. And that base is said to be overridden.
Example for Method Overriding:
class Dog
{
public void display()
{
System.out.println("I am A Dog");
}
}
class breed extends Dog
{
public void display()
{
System.out.println("Breed: German Shepard");
}
}
public class BreedTest
{
public static void main(String args[])
{
Dog d = new Dog(); // Animal reference and object
Dog b = new breed(); // Animal reference but Dog object
d.display(); // runs the method in Animal class
b.display(); // runs the method in Dog class
}
}
Data abstraction is the process of hiding the details but only displaying the relevant information to the users, which means hiding the implementation details and displaying only its functionalities. This is one of the main advantages of using abstraction.
Suppose a person is typing with the help of a keyboard on his/her computer. That person knows that pressing any alphabet on the keyboard, displays that alphabet on the screen of the monitor but he/she doesn’t know how the internal mechanism is working to display the alphabet.
Therefore, hiding the internal mechanism and showing only its output is an abstraction in this example.
In java, abstraction can be achieved in two ways.
Abstraction class.
Interfaces.
Abstraction class and Abstract methods:
An abstract class is a class that is declared with an abstract keyword.
An abstract class may or may not have abstract methods.
An object of an abstract class cannot be created, to access this class, it must be inherited.
Example:
abstract class ClassName {}
Abstract methods:
It is a method that can only be used with an abstract class.
It has no body.
An abstract method is also declared with an abstract keyword and ends with a semicolon(;) instead of curly braces({}).
Example:
public abstract void methodName();
Let us see it in an example:
// Abstract class
abstract class AbstractTest
{
public abstract void animals(); //abstract method
public void dog()
{
System.out.println("Dog barks");
}
}
class Cat extends AbstractTest //inheriting AbstractTest class
{
public void animals()
{
// animals body
System.out.println("Cat meows");
}
}
public class Main
{
public static void main(String[] args)
{
Cat c = new Cat(); // Create an object
c.animals();
c.dog();
}
}
Java supports three types of inheritance on the basis of class: single, multilevel, and hierarchical.
Whereas multiple and hybrid inheritance is supported through interface only.
Types of Inheritance in Java:
Single Inheritance
Multilevel Inheritance.
Hierarchical Inheritance.
Multiple Inheritance.
Hybrid Inheritance.
1. Single Inheritance:
It is a child and parent class relationship where a child class extends or inherits only from one class or superclass. In the below diagram, class B extends only one class which is A. Here class A is a parent class of B and B would be a child class of A.
Example of Single Inheritance in Java:
class SuperClass
{
public void methodSuper()
{
System.out.println("Super class method");
}
}
class SubClass extends SuperClass
{
public void methodBase()
{
System.out.println("Sub class method");
}
}
public class Main
{
public static void main(String args[])
{
SubClass s = new SubClass();
s.methodSuper();
s.methodBase();
}
}
Output of single Inheritance:
Super class method Base class method
2. Multilevel Inheritance:
It is a child and parent class relationship where one can inherit from a derived class, thereby making this derived class the base class for the new class. In the below diagram, class C is a subclass or child class of class B and class B is a child class of class A.
Example of Multilevel Inheritance in Java:
class FirstClass
{
public void displayFirst()
{
System.out.println("I am First Class");
}
}
class SecondClass extends FirstClass
{
public void displaySecond()
{
System.out.println("I am Second Class");
}
}
class ThirdClass extends SecondClass
{
public void displayThird()
{
System.out.println("I am Third Class");
}
}
public class Main
{
public static void main(String[] args)
{
ThirdClass three = new ThirdClass();
three.displayFirst();
three.displaySecond();
three.displayThird();
}
}
Output of MultilevelInheritance:
I am First Class I am Second Class I am Third Class
3. Hierarchical Inheritance:
In this type of inheritance, one superclass(base class) is inherited by many subclasses (derived class). That is inheriting the same class by many classes. In the below diagram class B and class, C inherits the same class A. Class A is parent class (or base class) of class B and class C.
Example of HierarchicalInheritance in Java:
class Animal
{
void Dog()
{
System.out.println("I am dog");}
}
class Cat extends Animal
{
void sleep()
{
System.out.println("I am Cat and I sleep");
}
}
class Horse extends Animal
{
void run()
{
System.out.println("I am Horse and I run");
}
}
public class Main
{
public static void main(String args[])
{
Horse h=new Horse();
h.Dog();
h.run();
Cat c=new Cat();
c.Dog();
c.sleep();
}
}
Output of HierarchicalInheritance:
I am dog I am Horse and I run I am dog I am Cat and I sleep
4. Multiple Inheritance:
In this relationship, one class(derived class) can inherit from more than one superclass. Java doesn’t support multiple inheritance because the derived class will have to manage the dependency on two base classes.
In java, we can achieve multiple inheritance only through Interfaces.
It is rarely used because it creates an unwanted problem in the hierarchy.
5. Hybrid Inheritance:
It is the relationship form by the combination of multiple inheritance. In a simple way, Hybrid inheritance is a combination of Single and Multiple inheritance. It is also not supported in Java and can only be achieved through interface just like Multiple Inheritance.
Encapsulation is one of the four fundamental OOP concepts. Encapsulation in Java is defined as the wrapping up of data(variable) under a single unit. The use of Encapsulation is to make sure that implementation detail or we can say sensitive data is hidden from the users. For this, Encapsulation is also known as data hiding.
Implementing the encapsulation in the program, the variables or data declared in one of the classes is hidden from any other class.
Encapsulation can be achieved in two ways:
Declare class variables/attributes as private, restricting other classes to access it.
Provide public setter and getter methods to modify and view the values of the variables.
Benefits of Encapsulation:
Data- hiding in Java.
The class field can be made read-only or write-only.
It provides the class the total control over the data.
Get and Set:
As we know the private variable cannot be accessed by other classes, but we can access them by providing getter and setter methods.
The get method returns the variable value.
The set method sets the value.
Note: Getter and Setter methods should start with get or set, followed by the variable name whose first letter should be in upper case. They both should be declared public. Since get returns value and set doesn’t get should be of data-type same as the variable it accesses and set must be declared void.
Syntax Example:
public class Student
{
private String name; // private
// Getter
public String getName()
{
return name;
}
// Setter
public void setName(String newName)
{
this.name = newName;
}
}
Let us go through a java example to understand better
Encapsulation in Java using setter and getter
class StudentInfo
{
private int id;
private String stdName;
private int stdAge;
//Getter methods
public int geStdiID()
{
return id;
}
public String getStdName()
{
return stdName;
}
public int getStdAge()
{
return stdAge;
}
// Setter methods
public void geStdiID(int newId)
{
id = newId;
}
public void getStdName(String newName)
{
stdName = newName;
}
public void getStdAge(int newAge)
{
stdAge = newAge;
}
}
public class EncapsTest
{
public static void main(String args[])
{
StudentInfo obj = new StudentInfo();
obj.geStdiID(1101);
obj.getStdName("Marshall");
obj.getStdAge(20);
System.out.println("Student Id: " + obj.geStdiID());
System.out.println("Student Name: " + obj.getStdName());
System.out.println("Student Age: " + obj.getStdAge());
}
}
It is the concept of using objects in programming. It is a paradigm that uses objects and classes that aim to implement real-world entities. The entities such as inheritance, abstraction, polymorphism, etc that are used in programming.
The main goal of an OOP is to tie together the data and its method in a single object so that no other block of code can access that data but only that function. And thus, it also makes it easier to work with.
The main principle of OOP are:
Inheritance.
Encapsulation.
Abstraction.
Polymorphism.
Inheritance:
It is one of the main features of Object-Oriented Programming (OOP). Inheritance is one of the processes or mechanisms in OOP in which one class(sub-class) acquires the properties(data members) and functionalities(methods) of another class(parent-class).
Super Class: The class whose properties and functionalities are inherited by the Subclass is known as the superclass(a parent class or a base class).
Sub Class: The class that inherits the property and behavior of the other class(Superclass) is known as subclass( a derived class, extended class, or child class).
Syntax:
class Super
{
//field and methods
}
class sub extends Super
{
//its own field and methods
}
Encapsulation is one of the four fundamental OOP concepts. Encapsulation in Java is defined as the wrapping up of data(variable) under a single unit. The use of Encapsulation is to make sure that implementation detail or we can say sensitive data is hidden from the users.
For this, Encapsulation is also known as data hiding.
Benefits of Encapsulation:
Data- hiding in Java.
The class field can be made read-only or write-only.
It provides the class the total control over the data.
Syntax Example:
public class Student
{
private String name; // private
// Getter
public String getName()
{
return name;
}
// Setter
public void setName(String newName)
{
this.name = newName;
}
}
Abstraction:
Data abstraction is the process of hiding the details but only displaying the relevant information to the users, which is hiding the implementation details and displaying only its functionalities. This is one of the main advantages of using abstraction.
Abstraction is one of the four major concepts behind object-oriented programming (OOP).
In java, abstraction can be achieved in two ways.
Abstraction class.
Interfaces.
1. Abstraction class.
An abstract class is a class that is declared with an abstract keyword.
An abstract class may or may not have abstract methods.
This class cannot create objects, to access this class, it must be inherited.
abstract class ClassName {
}
2. Interfaces
An Interface in Java is the same as class, like any other class, an interface can have methods and Variables.
Polymorphism means having many forms. The word “poly” means many and “morphs” means forms. In java, it is a concept that allows the user to perform a single action in different ways.
In Java polymorphism is mainly divided into two types:
1. Compile-time Polymorphism:
It is also known as static polymorphism. In this type of program, the flow of control is decided at compile time itself and if any error found, they are resolved at compile time. This can be achieved by method overloading.
2. Runtime Polymorphism:
It is also known as Dynamic Method Dispatch. It is a process in which a call to an overridden method is resolved at runtime. This type of polymorphism is achieved by Method Overriding.
It is one of the main features of Object-Oriented Programming (OOP). Inheritance is one of the processes or mechanisms in OOP in which one class(sub-class) acquires the properties(data members) and functionalities(methods) of another class(parent-class).
Importance of Inheritance:
For Code Reusability.
For Method Overriding (to achieve runtime polymorphism).
Important terms:
Super Class: The class whose properties and functionalities are inherited by the Subclass is known as superclass(a parent class or a base class).
Sub Class: The class that inherits the property and behavior of the other class(Superclass) is known as subclass( a derived class, extended class, or child class). The subclass can have its own fields and methods along with the fields and methods of the superclass.
Reusability: Inheritance supports the concept of “reusability”. This feature allows us to use the methods in the sub-class that is already present in the superclass, saving the time to rewrite the code.
extends: extends is the keyword that’s used by the base class so that it can inherit the properties of the superclass.
Syntax:
class Super
{
//field and methods
}
class sub extends Super
{
//its own field and methods
}
Basic Example for Inheritance:
class Dog
{
void dogName()
{
System.out.println("My Name is Bruno");
}
}
class Breed extends Dog
{
void myBreed()
{
System.out.println("German Shepard");
}
}
public class Main
{
public static void main(String args[])
{
Breed d = new Breed();
d.dogName();
d.myBreed();
}
}
Output:
My Name is Bruno German Shepard
In the above example, the Breed class inherits the method ‘dogName()‘ from the superclass with the help of a keyword ‘extends’.
Note: The Object is created for only the Breed class but not for the Dog class. That is we can access the methods without creating the object of the superclass. Although there are some concepts you need to know before inheriting the superclass, the method that the user wishes to inherit from the superclass cannot be private and also the superclass itself should not be declared private otherwise it cannot be inherited. ‘protected’ methods can be inherited.
Java does not support Multiple and Hybrid Inheritance but can be achieved by Interfaces.
Inheritance
1.Single Inheritance:
It refers to an inheritance where a child inherits or extends a single-parent class. Here class B extends class A.
single inheritance
2. Multilevel inheritance:
It refers to an inheritance where one class inherits from the derived class and making that derived class the superclass for the new class.
Here class C inherits from class B and class B inherits from class A.
Multiple Inheritance
3. Hierarchical Inheritance:
It refers to a relationship where more than one class can inherit or extends the same class. Here class B and class C inherit class A.
HierarchicalInheritance
4. Multiple Inheritance:
In this relationship, one class(derived class) can inherit from more than one superclass. Java doesn’t support multiple inheritance. check the diagram above.
5. Hybrid Inheritance:
A combination of more than one type of inheritance in a program is called Hybrid Inheritance. It is also not supported by Java. check the diagram above.
Click here to learn about each of the inheritances with examples.
Constructors and super Keyword in Inheritance.
In Inheritance, a subclass inherits all the members that are its fields, methods, and nested classes from its superclass. But Constructors are not members, so they cannot be inherited by subclasses, but the constructor of the superclass can be invoked from the subclass with the help of a super keyword. super Keyword refers directly to the superclass in its hierarchy. It is similar to this Keyword.
super is used to invoke the superclass constructor from a subclass. And also used when the members having the same name in the superclass and subclass and therefore need to differentiate between them.
Syntax of super Keyword:
class SuperclassTest
{
int num1, num2;
SuperclassTest(int num1, int num2)
{
this.num1 = num1;
this.num2 = num2;
}
public void getNum()
{
System.out.println("Numbers in super class are: " + num1 + " and: " + num2);
}
}
public class Subclass extends SuperclassTest
{
Subclass(int num1, int num2)
{
super(num1, num2); //use of super
}
public static void main(String argd[])
{
Subclass s = new Subclass(24, 30);
s.getNum();
}
}
Output:
Numbers in super class are: 24 and: 30
Java Program for Super keyword
Example of a super keyword to differentiate the members of the superclass from a subclass.
class SuperClass
{
int id = 20;
public void display()
{
System.out.println("Super Class display method");
}
}
public class SubClass extends SuperClass
{
int id = 10;
public void display()
{
System.out.println("Sub Class display method");
}
public void myMethods()
{
// Instantiating subclass
SubClass s = new SubClass();
// display method and value of sub class
s.display();
System.out.println("Sub Class id:" + s.id);
// display method and value of super class using super
super.display();
System.out.println("Super Class id::" + super.id);
}
public static void main(String args[])
{
SubClass sub = new SubClass();
sub.myMethods();
}
}
Output:
Base Class display method Sub Class id:10 Super Class display method Super Class id::20
If a method is to be called by passing a parameter as a value then it is said to be Call by Value. Here the changes made to the passed parameter do not affect the called method.
Example of call by value:
class CallByValue
{
void meth(int x, int y)
{
x = x + 10;
y = y - 20;
System.out.println("The result after the operation performed:");
System.out.println("a = " + x + "\t b = " + y);
}
}
public class JavaMain
{
public static void main(String args[])
{
CallByValue obj = new CallByValue();
int a =50, b = 100;
System.out.println("The value of a and b before the call :");
System.out.println("a = " + a + "\t b = " + b);
obj.meth(a, b);
System.out.println("The value of a and b after the call : ");
System.out.println("a = " + a + "\t b = " + b);
}
}
Output:
a = 50 b = 100
The result after the operation performed:
a = 60 b = 80
The value of a and b after the call :
a = 50 b = 100
call by reference in Java:
If a method is to be called by passing a parameter (not the value) as a reference then it is said to be Call by Reference. Here the changes are made to the passed parameter effect on the called method.
Example of call by reference:
class CallByRef
{
int x, y;
CallByRef(int i, int j)
{
x = i;
y = j;
}
/* pass an object */
void method(CallByRef p)
{
p.x = p.x + 2;
p.y = p.y + 2;
}
}
public class JavaMain
{
public static void main(String args[])
{
CallByRef obj = new CallByRef(10, 20);
int x = 10, y = 20;
System.out.println("The value of a and b before the call :");
System.out.println("a = " + obj.x + "\t b = " + obj.y);
obj.method(obj);
System.out.println("The value of a and b after the call : ");
System.out.println("a = " + obj.x + "\t b = " + obj.y);
}
}
Output:
The value of a and b before the call :
a = 10 b = 20
The value of a and b after the call :
a = 12 b = 22
Keywords in Java are also known as reserved words, are already defined in Java with a predefined meaning. These words cannot be used with variables or object name.
Example of using integer Keyword:
int number = 5;
List of Keywords used in Java are shown in the table:
Keywords
abstract
assert
boolean
break
byte
case
catch
char
do
double
else
enum
extends
final
finally
float
for
goto
if
implements
import
instanceof
int
interface
long
native
new
package
short
static
strictfp
super
volatile
while
this
throw
private
protected
public
return
throws
transient
try
void
Identifiers:
Identifier is the symbolic name given to the variables name, class name, method name, etc for identification reason so that the program can identify them throughout the program. The name is given by the user with their choice but by following naming rules.
These rules are:
An identifier cannot be a Java keyword.
Identifiers are case sensitive, that temp and Temp are different identifiers.
Identifiers must begin with a sequence of letters(A-Z, a-z) and digits(0-9), $ or _. Note that an identifier cannot have the first letter as a digit.
Type Casting is assigning a value of one data-type to a variable of another data-type.
When a value is assigned to another variable, their types might not be compatible with each other to store that value. For this situation, they need to be cast or converted explicitly. But if they are compatible then java converts the values automatically which is known as Automatic Type Conversion.
In Java, there are two types of casting:
Widening Casting (Implicit)
Narrowing Casting (Explicitly)
1. Widening Casting (Implicit):
Converting a data-type of smaller size to a type of larger size. It is also known as Automatic Type Conversion. byte -> short -> char -> int -> long -> float -> double
Example of Widening or Implicit Casting:
public class WideCast
{
public static void main(String[] args)
{
int i = 10;
long l = i; //converted automatically
float f = l; //converted automatically
System.out.println("Int value "+i);
System.out.println("Long value "+l);
System.out.println("Float value "+f);
}
}
Output:
Int value 10
Long value 10
Float value 10.0
2. Narrowing Casting (Explicit):
Converting a data-type of larger size (occupying larger space) to a type of smaller size. For this type of conversion programmer itself to perform the task. Here, unlike Widening Casting, JVM(Java Virtual Machine) does not take part. double -> float -> long -> int -> char -> short -> byte
Example of Narrowing or Explicit Casting:
public class NarrowCast
{
public static void main(String[] args)
{
double d = 200.04;
long l = (long)d; //converted manually
int i = (int)l; //converted manually
System.out.println("Double value "+d);
System.out.println("Long value "+l);
System.out.println("Int value "+i);
}
}
Data types specify the varying sizes and values in the variables that can be stored. That is every variable is assigned by data-types according to the need. And based on their respective data-types, the operating system allocates memory to that data-types.
There are two data types in Java:
Primitive data types: The primitive data types include boolean, char, byte, short, int, long, float and double.
Non-primitive data types: The non-primitive data types include Classes, Interfaces, and Arrays.
1. Primitive data types:
These are the most basic data types available in the Java language. There are eight primitive data-types available by Java:
Data type
Size
Description
byte
1 byte
Stores whole numbers from -128 to 127
short
2 bytes
Stores whole numbers from -128 to 127
char
2 bytes
Stores whole numbers from -32,768 to 32,767
int
4 bytes
Stores a single character/letter or ASCII values
long
8 bytes
Stores whole numbers from -2,147,483,648 to 2,147,483,647
float
4 bytes
Stores whole numbers from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
double
8 bytes
Stores fractional numbers. Sufficient for storing 6 to 7 decimal digits
boolean
1 bit
Stores true or false values
These are put into four group:
Integers: This group includes byte, short, int, and long, which are for whole-valued signed numbers.
Floating-point numbers: This group includes float and double, which represent numbers with fractional precision.
Characters: This group includes char, which represents symbols in a character set, like letters and numbers.
Boolean: This group includes boolean, which is a special type for representing true/false values.
Integers:
byte: It is an 8-bit signed two’s complement integer. The byte data type is used to save memory in large arrays. Its minimum value is -128 and the maximum value is 127. Its default value is 0. Example: byte x = 15; byte y = -12;
Short: The short data type is a 16-bit signed two’s complement integer. A short is 2 times smaller than an integer. Its minimum value is -32,768 and the maximum value is 32,767. Its default value is 0. And is also used to save memory. Example: short x = 1500; short y = -1200;
int: The int data type is a 32-bit signed two’s complement integer. It is a default data-type for integral values.Its minimum value is – 2,147,483,648 and maximum value is 2,147,483,647. Its default value is 0. Example: int x = 25; int y = -35;
long: The long data type is a 64-bit two’s complement integer. Its value-range lies between -9,223,372,036,854,775,808(-2^63) to 9,223,372,036,854,775,807 (2^63 -1) (inclusive). Its default value is 0. long is used when int is not large enough to store the value. Example: long x = 200000L; long y = -300000L;
Floating Point Types:
float: The float data type is a single-precision 32-bit IEEE 754 floating-point. It is used when the user needs to save memory in large arrays of floating-point numbers. float is never used for precise values such as for currency. Its default value is 0.0d. Example: float x = 234.5f;
double: The double data type is a double-precision 64-bit IEEE 754 floating-point. The double is generally used for decimal values just like float. The double also should never be used for precise values, such as currency. Its default value is 0.0d. Example: double x = 13.99d;
Characters:
The char data type is a single 16-bit Unicode character. The size of a character is 2 bytes. It is used to store single characters and must be enclosed within single quotes as shown in the example. Example:
char alphabet = 'A';
Boolean:
A boolean keyword is used to declare with the boolean data-type and represents one bit of information that is either true or false. Example:
boolean fun = true;
boolean bored = false;
2. Non-Primitive Data Types:
The non-primitive data types include Strings, Classes, Interfaces, and Arrays. These are also known as reference types because they refer to objects. Non-primitive types are created by the user/programmer and are not predefined by Java except one that is String and can have null values whereas primitive data types are predefined in Java and always has a value.
To learn about Non-Primitive Data Types click on the following: Strings, Classes, Interfaces, Arrays.