Unit - 3
Inheritance and Polymorphism
Inheritance is one of the main principles of OOP language. By using this principle one can inherit all the properties of other classes. Inheritance allows us to manage information in a hierarchical manner.
Inheritance use two types of class: Superclass and subclass. Superclass also known as parent or base class is the class whose properties are inherited while subclass also known as derived or child class is the class who inherits the properties.
To inherit a class we simply use the extend keyword which allows to inherit the definition of class to another as shown below:
Class subclass-name extends superclass-name {
// body of class
}
Lets look at a simple example of inheritance:
Class First { // Superclass.
Int x, y;
Void showxy() {
System.out.println("x and y: " + x + " " + y);
}
}
Class Second extends First { // Subclass Second by extending class First.
Int z;
Void showz() {
System.out.println("z: " + z);
}
Void sum() {
System.out.println("x+y+z: " + (x+y+z));
}
}
Class Example {
Public static void main(String args[]) {
First superOb = new First();
Second subOb = new Second();
SuperOb.x = 100;
SuperOb.y = 200;
System.out.println("Data of superclass: ");
SuperOb.showxy();
System.out.println();
/* The subclass can access all public members of its superclass. */
SubOb.x = 45;
SubOb.y = 10;
SubOb.z = 5;
System.out.println("Contents of subOb: ");
SubOb.showxy();
SubOb.showz();
System.out.println();
System.out.println("Sum of i, j and k in subOb:");
SubOb.sum();
}
}
Output
Data of superclass:
x and y: 100 200
Contents of subOb:
x and y: 45 10
z: 5
Sum of x, y and z in subOb:
x+y+z: 60
Significance of Inheritance
Inheritance is one of the most significant concept of object oriented programming which allow a class to inherit its properties to other class. This makes it easier to deploy and maintain an application.
Another benefit of using inheritance is code reusability. Code reusability means avoiding unnecessary code. In inheritance code can be used by other class and the subclass have to write its own unique properties only and rest of the properties will be inherited from the parent class or superclass.
Method overriding is also one benefit of using inheritance. Here a child class creates a method of same type as in parent class. In method overriding when we call the method, the child class method will be called. To call the parent class method we have to use super keyword.
Key takeaway
Inheritance is one of the main principles of OOP language. By using this principle one can inherit all the properties of other classes. Inheritance allows us to manage information in a hierarchical manner.
In Java, there are three types of inheritance based on class: single, multilayer, and hierarchical inheritance.
Multiple and hybrid inheritance are only enabled through interfaces in Java programming.
Many inheritance occurs when one class inherits from multiple classes. Consider the following scenario:
Single inheritance
A single inheritance occurs when a class inherits from another class. The Dog class inherits the Animal class in the example below, therefore there is just one inheritance.
Example
Class Animal{
Void eat(){System.out.println("eating...");}
}
Class Dog extends Animal{
Void bark(){System.out.println("barking...");}
}
Class TestInheritance{
Public static void main(String args[]){
Dog d=new Dog();
d.bark();
d.eat();
}}
Output:
Barking...
Eating...
Multilevel inheritance
Multilevel inheritance occurs when there is a chain of inheritance. As shown in the example below, the BabyDog class inherits from the Dog class, which in turn inherits from the Animal class, resulting in a multilayer inheritance.
Example
Class Animal{
Void eat(){System.out.println("eating...");}
}
Class Dog extends Animal{
Void bark(){System.out.println("barking...");}
}
Class BabyDog extends Dog{
Void weep(){System.out.println("weeping...");}
}
Class TestInheritance2{
Public static void main(String args[]){
BabyDog d=new BabyDog();
d.weep();
d.bark();
d.eat();
}}
Output:
Weeping...
Barking...
Eating...
Hierarchical inheritance
Hierarchical inheritance occurs when two or more classes inherit a single class. The Dog and Cat classes inherit the Animal class in the example below, indicating hierarchical inheritance.
Example
Class Animal{
Void eat(){System.out.println("eating...");}
}
Class Dog extends Animal{
Void bark(){System.out.println("barking...");}
}
Class Cat extends Animal{
Void meow(){System.out.println("meowing...");}
}
Class TestInheritance3{
Public static void main(String args[]){
Cat c=new Cat();
c.meow();
c.eat();
//c.bark();//C.T.Error
}}
Output:
Meowing...
Eating...
In Java, when inheritance is implemented in that case constructor of base class gets automatically called in derived class.
In heritance constructors are called in the order they are derived i.e. from superclass to subclass.
The order of execution of constructor in inheritance will be from superclass to subclass in spite of the fact that super keyword is used or not.
If super() is used it will be the first statement to be executed by the subclass constructor. And if super() is not used in that case default or non parameterized constructor of each superclass will be executed first.
Example
Class P{ //Super class
P(){
System.out.println(“Superclass constructor”);
}}
Class C1 extends P{ //Sub class1
C1(){
System.out.println(“First subclass constructor”);
}}
Class C2 extends C1{ //Sub class2
C2(){
System.out.println(“Second subclass constructor”);
}}
Class Example{
Public static void main(String[] args)
C2 c = new C2();
}
}
Output of above program is
Superclass constructor
First subclass constructor
Second subclass constructor
Multilevel Inheritance
When there is a chain of inheritance, it is known as multilevel inheritance. As you can see in the example given below, BabyDog class inherits the Dog class which again inherits the Animal class, so there is a multilevel inheritance.
File: TestInheritance2.java
- Class Animal{
- Void eat(){System.out.println("eating...");}
- }
- Class Dog extends Animal{
- Void bark(){System.out.println("barking...");}
- }
- Class BabyDog extends Dog{
- Void weep(){System.out.println("weeping...");}
- }
- Class TestInheritance2{
- Public static void main(String args[]){
- BabyDog d=new BabyDog();
- d.weep();
- d.bark();
- d.eat();
- }}
Output:
Weeping...
Barking...
Eating…
Method overriding
If subclass (child class) has the same method as declared in the parent class, it is known as method overriding in Java.
In other words, If a subclass provides the specific implementation of the method that has been declared by one of its parent class, it is known as method overriding.
Usage of Java Method Overriding
● Method overriding is used to provide the specific implementation of a method which is already provided by its superclass.
● Method overriding is used for runtime polymorphism
Rules for Java Method Overriding
- The method must have the same name as in the parent class
- The method must have the same parameter as in the parent class.
- There must be an IS-A relationship (inheritance).
Fig 1 – Method overriding
Understanding the problem without method overriding
Let's understand the problem that we may face in the program if we don't use method overriding.
- //Java Program to demonstrate why we need method overriding
- //Here, we are calling the method of parent class with child
- //class object.
- //Creating a parent class
- Class Vehicle{
- Void run(){System.out.println("Vehicle is running");}
- }
- //Creating a child class
- Class Bike extends Vehicle{
- Public static void main(String args[]){
- //creating an instance of child class
- Bike obj = new Bike();
- //calling the method with child class instance
- Obj.run();
- }
- }
Output:
Vehicle is running
Problem is that I have to provide a specific implementation of run() method in subclass that is why we use method overriding.
Example of method overriding
In this example, we have defined the run method in the subclass as defined in the parent class but it has some specific implementation. The name and parameter of the method are the same, and there is IS-A relationship between the classes, so there is method overriding.
- //Java Program to illustrate the use of Java Method Overriding
- //Creating a parent class.
- Class Vehicle{
- //defining a method
- Void run(){System.out.println("Vehicle is running");}
- }
- //Creating a child class
- Class Bike2 extends Vehicle{
- //defining the same method as in the parent class
- Void run(){System.out.println("Bike is running safely");}
- Public static void main(String args[]){
- Bike2 obj = new Bike2();//creating object
- Obj.run();//calling method
- }
- }
Output:
Bike is running safely
A real example of Java Method Overriding
Consider a scenario where Bank is a class that provides functionality to get the rate of interest. However, the rate of interest varies according to banks. For example, SBI, ICICI and AXIS banks could provide 8%, 7%, and 9% rate of interest.
Fig 2 - Example
Key takeaway
If subclass (child class) has the same method as declared in the parent class, it is known as method overriding in Java.
In other words, If a subclass provides the specific implementation of the method that has been declared by one of its parent class, it is known as method overriding.
Following are the scenarios where the super keyword is used.
● It is used to differentiate the members of superclass from the members of subclass, if they have same names.
● It is used to invoke the superclass constructor from subclass.
Differentiating the Members
If a class is inheriting the properties of another class. And if the members of the superclass have the names same as the sub class, to differentiate these variables we use super keyword as shown below.
Super.variable
Super.method();
Sample Code
This section provides you a program that demonstrates the usage of the super keyword.
In the given program, you have two classes namely Sub_class and Super_class, both have a method named display() with different implementations, and a variable named num with different values. We are invoking display() method of both classes and printing the value of the variable num of both classes. Here you can observe that we have used super keyword to differentiate the members of superclass from subclass.
Copy and paste the program in a file with name Sub_class.java.
Example
Class Super_class {
Int num = 20;
// display method of superclass
Public void display() {
System.out.println("This is the display method of superclass");
}
}
Public class Sub_class extends Super_class {
Int num = 10;
// display method of sub class
Public void display() {
System.out.println("This is the display method of subclass");
}
Public void my_method() {
// Instantiating subclass
Sub_class sub = new Sub_class();
// Invoking the display() method of sub class
Sub.display();
// Invoking the display() method of superclass
Super.display();
// printing the value of variable num of subclass
System.out.println("value of the variable named num in sub class:"+ sub.num);
// printing the value of variable num of superclass
System.out.println("value of the variable named num in super class:"+ super.num);
}
Public static void main(String args[]) {
Sub_class obj = new Sub_class();
Obj.my_method();
}
}
Compile and execute the above code using the following syntax.
Javac Super_Demo
Java Super
On executing the program, you will get the following result −
Output
This is the display method of subclass
This is the display method of superclass
Value of the variable named num in sub class:10
Value of the variable named num in super class:20
It refers to immediate parent class object. There are 3 ways to use the ‘super’ keyword:
- To refer immediate parent class instance variable.
- To invoke immediate parent class method.
- To invoke immediate parent class constructor.
Program to refer immediate parent class instance variable using super keyword
Class transport
{
Int maxspeed = 200;
}
Class vehicle extends transport
{
Int maxspeed =100;
}
Class car extends vehicle
{
Int maxspeed = 120;
Void disp()
{System.out.println("Max speed= "+super.maxspeed);
}
}
Class veh
{
Public static void main(String arg[])
{
Car c = new car();
c.disp();
}
}
Output:
Max speed= 100
Program to invoke immediate parent class method
Class transport
{
Void message()
{
System.out.println("transport");
}
}
Class vehicle extends transport
{
Void message()
{
System.out.println("vehicle");
}
}
Class car extends vehicle
{
Int maxspeed = 120;
Void message()
{
System.out.println("car");
}
Void display()
{
Message();
Super.message();
}
}
Class veh
{
Public static void main(String arg[])
{
Car c = new car();
c.display();}
}
Output:
Car
Vehicle
Program to invoke immediate parent class constructor
Class vehicle
{
Vehicle()
{
System.out.println("vehicle");
}
}
Class car extends vehicle
{
Car()
{
Super();
System.out.println("car");
}
}
Class veh
{
Public static void main(String arg[])
{
Car c = new car();
}
}
Output:
Vehicle
Car
In Java, the keyword final is used to limit some functionality. The final keyword can be used to declare variables, methods, and classes.
Using final with inheritance
We must declare methods with the final keyword during inheritance, and we must follow the same implementation throughout all derived classes. It's worth noting that declaring final methods at the start of inheritance isn't required (base class always). We can define a final method in any subclass to ensure that if another class extends that subclass, it must implement the method in the same way as that subclass.
Example
// Java program to illustrate
// use of final with inheritance
// base class
Abstract class Shape
{
Private double width;
Private double height;
// Shape class parameterized constructor
Public Shape(double width, double height)
{
This.width = width;
This.height = height;
}
// getWidth method is declared as final
// so any class extending
// Shape can't override it
Public final double getWidth()
{
Return width;
}
// getHeight method is declared as final
// so any class extending Shape
// can not override it
Public final double getHeight()
{
Return height;
}
// method getArea() declared abstract because
// it upon its subclasses to provide
// complete implementation
Abstract double getArea();
}
// derived class one
Class Rectangle extends Shape
{
// Rectangle class parameterized constructor
Public Rectangle(double width, double height)
{
// calling Shape class constructor
Super(width, height);
}
// getArea method is overridden and declared
// as final so any class extending
// Rectangle can't override it
@Override
Final double getArea()
{
Return this.getHeight() * this.getWidth();
}
}
//derived class two
Class Square extends Shape
{
// Square class parameterized constructor
Public Square(double side)
{
// calling Shape class constructor
Super(side, side);
}
// getArea method is overridden and declared as
// final so any class extending
// Square can't override it
@Override
Final double getArea()
{
Return this.getHeight() * this.getWidth();
}
}
// Driver class
Public class Test
{
Public static void main(String[] args)
{
// creating Rectangle object
Shape s1 = new Rectangle(10, 20);
// creating Square object
Shape s2 = new Square(10);
// getting width and height of s1
System.out.println("width of s1 : "+ s1.getWidth());
System.out.println("height of s1 : "+ s1.getHeight());
// getting width and height of s2
System.out.println("width of s2 : "+ s2.getWidth());
System.out.println("height of s2 : "+ s2.getHeight());
//getting area of s1
System.out.println("area of s1 : "+ s1.getArea());
//getting area of s2
System.out.println("area of s2 : "+ s2.getArea());
}
}
Output
Width of s1 : 10.0
Height of s1: 20.0
Width of s2: 10.0
Height of s2: 10.0
Area of s1: 200.0
Area of s2: 100.0
Using final to Prevent Inheritance
When a class is designated final, it cannot be subclassed, meaning it cannot be extended by another class. This is especially handy when designing immutable classes, such as the standard String class. The final keyword with a class is seen in the following fragment:
Final class A
{
// methods and fields
}
// The following class is illegal.
Class B extends A
{
// ERROR! Can't subclass A
}
Please keep in mind that
● When you declare a class as final, you're also declaring all of its methods as final.
● It is forbidden to declare a class as both abstract and final, because an abstract class is unfinished in and of itself, relying on its subclasses for complete implementations. See Abstract Classes in Java for additional information on abstract classes.
Using final to Prevent Overriding
When a method is marked as final, subclasses are unable to override it. This is done by the Object class, which has a number of final methods. The last keyword with a method is seen in the following fragment:
Class A
{
Final void m1()
{
System.out.println("This is a final method.");
}
}
Class B extends A
{
Void m1()
{
// ERROR! Can't override.
System.out.println("Illegal!");
}
}
Java normally resolves method calls dynamically at runtime. This is referred to as late binding or dynamic binding. A call to one can be resolved at build time because final methods cannot be overridden. This is referred to as "early" or "static" binding.
Key takeaway
In Java, the keyword final is used to limit some functionality. The final keyword can be used to declare variables, methods, and classes.
Polymorphism can be defined as the ability to take different forms. It occurs when inheritance is used to have many classes that are related to each other.
Polymorphism most commonly used when a parent class reference is made to refer to a child class object.
Being one of the most important features of OOP, it must be supported by all languages based on OOP. Polymorphism in Java gives us the flexibility to use all the inherited properties of superclass to perform a task.
In real life, the simplest example to explain the concept of polymorphism is a person class. A single person can have different relationship with other person, like a mother, a daughter, a sister, a friend, an employee etc.
To better understand the concept of polymorphism we have to take a look at an example.
Consider a superclass named “Shapes” having a method name area(). The subclasses of this superclass can be Square, Rectangle, Triangle or any other shape. Using inheritance the subclass inherits the area() method also, but each shape has its own way of calculating area. Hence we can see that method name is same but it is used in different forms.
Class Shapes {
Public void area() {
System.out.println("Area of shape can be calculated as: \n");
}
}
Class Square extends Shapes {
Public void area() {
System.out.println("Area of Square is side * side ");
}
}
Class Rectangle extends Shapes {
Public void area() {
System.out.println("Area of Rectangle is base * height ");
}
}
Class Main {
Public static void main(String[] args) {
Shapes myShape = new Shapes(); // Create a Shapes object
Shapes mySquare = new Square(); // Create a Triangle object
Shapes myRectangle = new Rectangle(); // Create a Circle object
MyShape.area();
MySquare.area();
MyRectangle.area();
}
}
Output
Area of shape can be calculated as:
Area of Square is side * side
Area of Rectangle is base * height
Significance of Polymorphism in Java
The most significant use of polymorphism in Java is to write a method in different ways having multiple functionalities, with same method name.
Polymorphism helps to achieve consistency in a code.
Advantages of Polymorphism
- Code can be reusable in polymorphism, which means the classes that are already written can be used many times.
- We can use a single variable to store data values in multiple definition of methods. It will not change the value of a variable in the superclass, in fact allows storing subclass variable data also.
- Polymorphism allows lesser line of code, which helps the programmer to debug in case of error.
Types of polymorphism
Java supports two types of polymorphism:
- Compile time polymorphism
- Runtime polymorphism
Compile Time Polymorphism
It is also known as static polymorphism in Java. In this type, method call is made at compile time.
Compile type polymorphism is achieved through the concept of method overloading and operator overloading. However operator overloading is not supported in Java.
Method overloading can be defined as overloading of methods having same name i.e. when a class consist of multiple methods having same name but differs in the number, types, parameters and the return type of methods.
Java gives the flexibility to the user to create as many methods of same as long as it can be differentiate between them by the type and number of parameters.
Method overloading is explained in detail below.
Runtime Polymorphism
In Java, runtime polymorphism is also referred as Dynamic Binding or Dynamic Method Dispatch. In this process, at runtime we can call to an overridden method to process dynamically rather at compile time.
To implement the runtime polymorphism we us method overridden.
Method overridden happens when the child or subclass has a method with same definition as the parent or superclass, then that function overrides the function in the superclass.
In this process, a reference variable of a superclass is used to called an overridden method.
Dynamic binding
The method to be called is not determined by the compiler in dynamic binding. Dynamic binding is exemplified through overriding. Both the parent and child classes have the same approach for overriding.
Dynamic binding occurs when the type of an object is determined at run-time.
Example
Class Animal{
Void eat(){System.out.println("animal is eating...");}
}
Class Dog extends Animal{
Void eat(){System.out.println("dog is eating...");}
Public static void main(String args[]){
Animal a=new Dog();
a.eat();
}
}
Output
Output: dog is eating…
Because the instance of Dog is also an instance of Animal, the compiler cannot detect the object type in the previous example. As a result, the compiler only knows its basic type.
Key takeaway
Polymorphism can be defined as the ability to take different forms. It occurs when inheritance is used to have many classes that are related to each other.
In Java, method overriding is a technique through which a subclass or derived class can provide its own version of a method whose implementation is given by one its super class.
By doing this a subclass is defining a method having same name, same parameter, and same return type similar to method in the superclass. Then the method in the subclass is said to override the method in the superclass.
The concept of runtime polymorphism in Java can be implemented using Method overriding.
The next important question is which class method will be executed. So the answer is
- When an object of a parent class makes a call to method, then the parent class method will be executed.
- When an object of a child class makes a call to method, then the child class method will be executed.
Hence, the type of object used for referring determines which version of the method will be executed in the case of overridden method.
A simple example showing how overridden method are created and called.
//Parent class declaration
Class Parent{
Void display() //method defined in parent class
{
System.out.println(Method of parent class”);
}
}
//Child class declaration
Class Child extends Parent{
Void display() //child class method overrides parent class method
{
System.out.println(Method of child class”);
}
}
Class Demo{
Public static void main(String[] args)
{
Parent p = new Parent(); // object of parent class
Parent o = new Child(); // object of child class
p.display(); //reference made to parent class method by object p
o.display(); //reference made to child class method by object o
}
}
Output
Method of parent class
Method of child class
Rules for Method Overriding
- Overridden method must have same name and parameters.
- Method which is declared as final cannot be overridden.
- Static methods cannot be used to override.
- Overridden is not possible in private method.
- The return type of overriding method must be same.
- Constructors cannot be override.
- IS-A relationship must be fulfill in method overridden technique.
Key takeaway
In Java, method overriding is a technique through which a subclass or derived class can provide its own version of a method whose implementation is given by one its super class.
Dynamic binding is exemplified through overriding. Both the parent and child classes have the same approach for overriding.
Abstraction, according to the definition, is the ability to deal with ideas rather than occurrences. When it comes to email, for example, intricate information like what happens when you send an e-mail and the protocol your e-mail server utilises are hidden from the user. As a result, all you have to do to send an email is input the content, include the recipient's address, and click send.
Similarly, in Object-oriented programming, abstraction is the process of hiding implementation details from the user and simply providing functionality. To put it another way, the user will be given knowledge about what the object does rather than how it does it.
Abstract classes and interfaces are used in Java to achieve abstraction.
Abstract Classes
Abstract class is a type of class that has the abstract keyword in its declaration.
● Abstract classes may or may not contain abstract methods (public void get();).
● However, a class must be designated abstract if it has at least one abstract method.
● A class that has been declared abstract cannot be instantiated.
● You must inherit an abstract class from another class and supply implementations for the abstract methods in it in order to use it.
● You must supply implementations for all abstract methods in an abstract class if you inherit it.
Example
This section shows you how to use the abstract class. Simply use the abstract keyword before the class keyword in the class definition to create an abstract class.
/* File name: Employee.java */
Public abstract class Employee {
Private String name;
Private String address;
Private int number;
Public Employee(String name, String address, int number) {
System.out.println("Constructing an Employee");
This.name = name;
This.address = address;
This.number = number;
}
Public double computePay() {
System.out.println("Inside Employee computePay");
Return 0.0;
}
Public void mailCheck() {
System.out.println("Mailing a check to " + this.name + " " + this.address);
}
Public String toString() {
Return name + " " + address + " " + number;
}
Public String getName() {
Return name;
}
Public String getAddress() {
Return address;
}
Public void setAddress(String newAddress) {
Address = newAddress;
}
Public int getNumber() {
Return number;
}
}
Except for abstract methods, the Employee class is identical to a regular Java class. The class has three fields, seven methods, and one function Object() { [native code] }, but it is now abstract.
You may now attempt to instantiate the Employee class as follows:
/* File name : AbstractDemo.java */
Public class AbstractDemo {
Public static void main(String [] args) {
/* Following is not allowed and would raise error */
Employee e = new Employee("George W.", "Houston, TX", 43);
System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}
When you compile the above class, it gives you the following error −
Employee.java:46: Employee is abstract; cannot be instantiated
Employee e = new Employee("George W.", "Houston, TX", 43);
^
1 error
Inheriting the Abstract class
We may inherit the properties of the Employee class in the same way that we can inherit the properties of concrete classes in the following method:
Example
/* File name : Salary.java */
Public class Salary extends Employee {
Private double salary; // Annual salary
Public Salary(String name, String address, int number, double salary) {
Super(name, address, number);
SetSalary(salary);
}
Public void mailCheck() {
System.out.println("Within mailCheck of Salary class ");
System.out.println("Mailing check to " + getName() + " with salary " + salary);
}
Public double getSalary() {
Return salary;
}
Public void setSalary(double newSalary) {
If(newSalary >= 0.0) {
Salary = newSalary;
}
}
Public double computePay() {
System.out.println("Computing salary pay for " + getName());
Return salary/52;
}
}
You can't instantiate the Employee class here, but you can instantiate the Salary Class, and you can access all three fields and seven methods of the Employee class using this instance, as seen below.
/* File name : AbstractDemo.java */
Public class AbstractDemo {
Public static void main(String [] args) {
Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
System.out.println("Call mailCheck using Salary reference --");
s.mailCheck();
System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}
Output
Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0
Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.0
Abstract Methods
If you want a class to contain a method but the actual implementation of that method to be determined by child classes, designate the method as an abstract in the parent class.
● To declare a method abstract, use the abstract keyword.
● In the method declaration, the abstract keyword must come before the method name.
● There is no method body in an abstract method, only a method signature.
● An abstract method will have a semicolon (;) at the end instead of curly braces.
The abstract technique is demonstrated in the following example.
Example
Public abstract class Employee {
Private String name;
Private String address;
Private int number;
Public abstract double computePay();
// Remainder of class definition
}
Declaring a method abstract has two ramifications.
● It must be specified as abstract in the class that contains it.
● Any class that inherits the current class must either override or declare the abstract method.
Note that a descendant class must implement the abstract method at some point; otherwise, you'll wind up with a hierarchy of abstract classes that can't be created.
If the Salary class derives from the Employee class, the computePay() method should be implemented as shown below.
/* File name : Salary.java */
Public class Salary extends Employee {
Private double salary; // Annual salary
Public double computePay() {
System.out.println("Computing salary pay for " + getName());
Return salary/52;
}
// Remainder of class definition
}
Key takeaway
Abstraction, according to the definition, is the ability to deal with ideas rather than occurrences. When it comes to email, for example, intricate information like what happens when you send an e-mail and the protocol your e-mail server utilises are hidden from the user.
References:
- Programming in Java. Second Edition. Oxford Higher Education. (Sachin Malhotra/Saura V Choudhary)
- CORE JAVA For Beginners. (Rashmi Kanta Das), Vikas Publication
- JAVA Complete Reference (9th Edition) Herbert Schelidt.
- T. Budd, “Understanding Object- Oriented Programming with Java”, Pearson Education, Updated Edition (New Java 2 Coverage), 1999.
Unit - 3
Inheritance and Polymorphism
Inheritance is one of the main principles of OOP language. By using this principle one can inherit all the properties of other classes. Inheritance allows us to manage information in a hierarchical manner.
Inheritance use two types of class: Superclass and subclass. Superclass also known as parent or base class is the class whose properties are inherited while subclass also known as derived or child class is the class who inherits the properties.
To inherit a class we simply use the extend keyword which allows to inherit the definition of class to another as shown below:
Class subclass-name extends superclass-name {
// body of class
}
Lets look at a simple example of inheritance:
Class First { // Superclass.
Int x, y;
Void showxy() {
System.out.println("x and y: " + x + " " + y);
}
}
Class Second extends First { // Subclass Second by extending class First.
Int z;
Void showz() {
System.out.println("z: " + z);
}
Void sum() {
System.out.println("x+y+z: " + (x+y+z));
}
}
Class Example {
Public static void main(String args[]) {
First superOb = new First();
Second subOb = new Second();
SuperOb.x = 100;
SuperOb.y = 200;
System.out.println("Data of superclass: ");
SuperOb.showxy();
System.out.println();
/* The subclass can access all public members of its superclass. */
SubOb.x = 45;
SubOb.y = 10;
SubOb.z = 5;
System.out.println("Contents of subOb: ");
SubOb.showxy();
SubOb.showz();
System.out.println();
System.out.println("Sum of i, j and k in subOb:");
SubOb.sum();
}
}
Output
Data of superclass:
x and y: 100 200
Contents of subOb:
x and y: 45 10
z: 5
Sum of x, y and z in subOb:
x+y+z: 60
Significance of Inheritance
Inheritance is one of the most significant concept of object oriented programming which allow a class to inherit its properties to other class. This makes it easier to deploy and maintain an application.
Another benefit of using inheritance is code reusability. Code reusability means avoiding unnecessary code. In inheritance code can be used by other class and the subclass have to write its own unique properties only and rest of the properties will be inherited from the parent class or superclass.
Method overriding is also one benefit of using inheritance. Here a child class creates a method of same type as in parent class. In method overriding when we call the method, the child class method will be called. To call the parent class method we have to use super keyword.
Key takeaway
Inheritance is one of the main principles of OOP language. By using this principle one can inherit all the properties of other classes. Inheritance allows us to manage information in a hierarchical manner.
In Java, there are three types of inheritance based on class: single, multilayer, and hierarchical inheritance.
Multiple and hybrid inheritance are only enabled through interfaces in Java programming.
Many inheritance occurs when one class inherits from multiple classes. Consider the following scenario:
Single inheritance
A single inheritance occurs when a class inherits from another class. The Dog class inherits the Animal class in the example below, therefore there is just one inheritance.
Example
Class Animal{
Void eat(){System.out.println("eating...");}
}
Class Dog extends Animal{
Void bark(){System.out.println("barking...");}
}
Class TestInheritance{
Public static void main(String args[]){
Dog d=new Dog();
d.bark();
d.eat();
}}
Output:
Barking...
Eating...
Multilevel inheritance
Multilevel inheritance occurs when there is a chain of inheritance. As shown in the example below, the BabyDog class inherits from the Dog class, which in turn inherits from the Animal class, resulting in a multilayer inheritance.
Example
Class Animal{
Void eat(){System.out.println("eating...");}
}
Class Dog extends Animal{
Void bark(){System.out.println("barking...");}
}
Class BabyDog extends Dog{
Void weep(){System.out.println("weeping...");}
}
Class TestInheritance2{
Public static void main(String args[]){
BabyDog d=new BabyDog();
d.weep();
d.bark();
d.eat();
}}
Output:
Weeping...
Barking...
Eating...
Hierarchical inheritance
Hierarchical inheritance occurs when two or more classes inherit a single class. The Dog and Cat classes inherit the Animal class in the example below, indicating hierarchical inheritance.
Example
Class Animal{
Void eat(){System.out.println("eating...");}
}
Class Dog extends Animal{
Void bark(){System.out.println("barking...");}
}
Class Cat extends Animal{
Void meow(){System.out.println("meowing...");}
}
Class TestInheritance3{
Public static void main(String args[]){
Cat c=new Cat();
c.meow();
c.eat();
//c.bark();//C.T.Error
}}
Output:
Meowing...
Eating...
In Java, when inheritance is implemented in that case constructor of base class gets automatically called in derived class.
In heritance constructors are called in the order they are derived i.e. from superclass to subclass.
The order of execution of constructor in inheritance will be from superclass to subclass in spite of the fact that super keyword is used or not.
If super() is used it will be the first statement to be executed by the subclass constructor. And if super() is not used in that case default or non parameterized constructor of each superclass will be executed first.
Example
Class P{ //Super class
P(){
System.out.println(“Superclass constructor”);
}}
Class C1 extends P{ //Sub class1
C1(){
System.out.println(“First subclass constructor”);
}}
Class C2 extends C1{ //Sub class2
C2(){
System.out.println(“Second subclass constructor”);
}}
Class Example{
Public static void main(String[] args)
C2 c = new C2();
}
}
Output of above program is
Superclass constructor
First subclass constructor
Second subclass constructor
Multilevel Inheritance
When there is a chain of inheritance, it is known as multilevel inheritance. As you can see in the example given below, BabyDog class inherits the Dog class which again inherits the Animal class, so there is a multilevel inheritance.
File: TestInheritance2.java
- Class Animal{
- Void eat(){System.out.println("eating...");}
- }
- Class Dog extends Animal{
- Void bark(){System.out.println("barking...");}
- }
- Class BabyDog extends Dog{
- Void weep(){System.out.println("weeping...");}
- }
- Class TestInheritance2{
- Public static void main(String args[]){
- BabyDog d=new BabyDog();
- d.weep();
- d.bark();
- d.eat();
- }}
Output:
Weeping...
Barking...
Eating…
Method overriding
If subclass (child class) has the same method as declared in the parent class, it is known as method overriding in Java.
In other words, If a subclass provides the specific implementation of the method that has been declared by one of its parent class, it is known as method overriding.
Usage of Java Method Overriding
● Method overriding is used to provide the specific implementation of a method which is already provided by its superclass.
● Method overriding is used for runtime polymorphism
Rules for Java Method Overriding
- The method must have the same name as in the parent class
- The method must have the same parameter as in the parent class.
- There must be an IS-A relationship (inheritance).
Fig 1 – Method overriding
Understanding the problem without method overriding
Let's understand the problem that we may face in the program if we don't use method overriding.
- //Java Program to demonstrate why we need method overriding
- //Here, we are calling the method of parent class with child
- //class object.
- //Creating a parent class
- Class Vehicle{
- Void run(){System.out.println("Vehicle is running");}
- }
- //Creating a child class
- Class Bike extends Vehicle{
- Public static void main(String args[]){
- //creating an instance of child class
- Bike obj = new Bike();
- //calling the method with child class instance
- Obj.run();
- }
- }
Output:
Vehicle is running
Problem is that I have to provide a specific implementation of run() method in subclass that is why we use method overriding.
Example of method overriding
In this example, we have defined the run method in the subclass as defined in the parent class but it has some specific implementation. The name and parameter of the method are the same, and there is IS-A relationship between the classes, so there is method overriding.
- //Java Program to illustrate the use of Java Method Overriding
- //Creating a parent class.
- Class Vehicle{
- //defining a method
- Void run(){System.out.println("Vehicle is running");}
- }
- //Creating a child class
- Class Bike2 extends Vehicle{
- //defining the same method as in the parent class
- Void run(){System.out.println("Bike is running safely");}
- Public static void main(String args[]){
- Bike2 obj = new Bike2();//creating object
- Obj.run();//calling method
- }
- }
Output:
Bike is running safely
A real example of Java Method Overriding
Consider a scenario where Bank is a class that provides functionality to get the rate of interest. However, the rate of interest varies according to banks. For example, SBI, ICICI and AXIS banks could provide 8%, 7%, and 9% rate of interest.
Fig 2 - Example
Key takeaway
If subclass (child class) has the same method as declared in the parent class, it is known as method overriding in Java.
In other words, If a subclass provides the specific implementation of the method that has been declared by one of its parent class, it is known as method overriding.
Following are the scenarios where the super keyword is used.
● It is used to differentiate the members of superclass from the members of subclass, if they have same names.
● It is used to invoke the superclass constructor from subclass.
Differentiating the Members
If a class is inheriting the properties of another class. And if the members of the superclass have the names same as the sub class, to differentiate these variables we use super keyword as shown below.
Super.variable
Super.method();
Sample Code
This section provides you a program that demonstrates the usage of the super keyword.
In the given program, you have two classes namely Sub_class and Super_class, both have a method named display() with different implementations, and a variable named num with different values. We are invoking display() method of both classes and printing the value of the variable num of both classes. Here you can observe that we have used super keyword to differentiate the members of superclass from subclass.
Copy and paste the program in a file with name Sub_class.java.
Example
Class Super_class {
Int num = 20;
// display method of superclass
Public void display() {
System.out.println("This is the display method of superclass");
}
}
Public class Sub_class extends Super_class {
Int num = 10;
// display method of sub class
Public void display() {
System.out.println("This is the display method of subclass");
}
Public void my_method() {
// Instantiating subclass
Sub_class sub = new Sub_class();
// Invoking the display() method of sub class
Sub.display();
// Invoking the display() method of superclass
Super.display();
// printing the value of variable num of subclass
System.out.println("value of the variable named num in sub class:"+ sub.num);
// printing the value of variable num of superclass
System.out.println("value of the variable named num in super class:"+ super.num);
}
Public static void main(String args[]) {
Sub_class obj = new Sub_class();
Obj.my_method();
}
}
Compile and execute the above code using the following syntax.
Javac Super_Demo
Java Super
On executing the program, you will get the following result −
Output
This is the display method of subclass
This is the display method of superclass
Value of the variable named num in sub class:10
Value of the variable named num in super class:20
It refers to immediate parent class object. There are 3 ways to use the ‘super’ keyword:
- To refer immediate parent class instance variable.
- To invoke immediate parent class method.
- To invoke immediate parent class constructor.
Program to refer immediate parent class instance variable using super keyword
Class transport
{
Int maxspeed = 200;
}
Class vehicle extends transport
{
Int maxspeed =100;
}
Class car extends vehicle
{
Int maxspeed = 120;
Void disp()
{System.out.println("Max speed= "+super.maxspeed);
}
}
Class veh
{
Public static void main(String arg[])
{
Car c = new car();
c.disp();
}
}
Output:
Max speed= 100
Program to invoke immediate parent class method
Class transport
{
Void message()
{
System.out.println("transport");
}
}
Class vehicle extends transport
{
Void message()
{
System.out.println("vehicle");
}
}
Class car extends vehicle
{
Int maxspeed = 120;
Void message()
{
System.out.println("car");
}
Void display()
{
Message();
Super.message();
}
}
Class veh
{
Public static void main(String arg[])
{
Car c = new car();
c.display();}
}
Output:
Car
Vehicle
Program to invoke immediate parent class constructor
Class vehicle
{
Vehicle()
{
System.out.println("vehicle");
}
}
Class car extends vehicle
{
Car()
{
Super();
System.out.println("car");
}
}
Class veh
{
Public static void main(String arg[])
{
Car c = new car();
}
}
Output:
Vehicle
Car
In Java, the keyword final is used to limit some functionality. The final keyword can be used to declare variables, methods, and classes.
Using final with inheritance
We must declare methods with the final keyword during inheritance, and we must follow the same implementation throughout all derived classes. It's worth noting that declaring final methods at the start of inheritance isn't required (base class always). We can define a final method in any subclass to ensure that if another class extends that subclass, it must implement the method in the same way as that subclass.
Example
// Java program to illustrate
// use of final with inheritance
// base class
Abstract class Shape
{
Private double width;
Private double height;
// Shape class parameterized constructor
Public Shape(double width, double height)
{
This.width = width;
This.height = height;
}
// getWidth method is declared as final
// so any class extending
// Shape can't override it
Public final double getWidth()
{
Return width;
}
// getHeight method is declared as final
// so any class extending Shape
// can not override it
Public final double getHeight()
{
Return height;
}
// method getArea() declared abstract because
// it upon its subclasses to provide
// complete implementation
Abstract double getArea();
}
// derived class one
Class Rectangle extends Shape
{
// Rectangle class parameterized constructor
Public Rectangle(double width, double height)
{
// calling Shape class constructor
Super(width, height);
}
// getArea method is overridden and declared
// as final so any class extending
// Rectangle can't override it
@Override
Final double getArea()
{
Return this.getHeight() * this.getWidth();
}
}
//derived class two
Class Square extends Shape
{
// Square class parameterized constructor
Public Square(double side)
{
// calling Shape class constructor
Super(side, side);
}
// getArea method is overridden and declared as
// final so any class extending
// Square can't override it
@Override
Final double getArea()
{
Return this.getHeight() * this.getWidth();
}
}
// Driver class
Public class Test
{
Public static void main(String[] args)
{
// creating Rectangle object
Shape s1 = new Rectangle(10, 20);
// creating Square object
Shape s2 = new Square(10);
// getting width and height of s1
System.out.println("width of s1 : "+ s1.getWidth());
System.out.println("height of s1 : "+ s1.getHeight());
// getting width and height of s2
System.out.println("width of s2 : "+ s2.getWidth());
System.out.println("height of s2 : "+ s2.getHeight());
//getting area of s1
System.out.println("area of s1 : "+ s1.getArea());
//getting area of s2
System.out.println("area of s2 : "+ s2.getArea());
}
}
Output
Width of s1 : 10.0
Height of s1: 20.0
Width of s2: 10.0
Height of s2: 10.0
Area of s1: 200.0
Area of s2: 100.0
Using final to Prevent Inheritance
When a class is designated final, it cannot be subclassed, meaning it cannot be extended by another class. This is especially handy when designing immutable classes, such as the standard String class. The final keyword with a class is seen in the following fragment:
Final class A
{
// methods and fields
}
// The following class is illegal.
Class B extends A
{
// ERROR! Can't subclass A
}
Please keep in mind that
● When you declare a class as final, you're also declaring all of its methods as final.
● It is forbidden to declare a class as both abstract and final, because an abstract class is unfinished in and of itself, relying on its subclasses for complete implementations. See Abstract Classes in Java for additional information on abstract classes.
Using final to Prevent Overriding
When a method is marked as final, subclasses are unable to override it. This is done by the Object class, which has a number of final methods. The last keyword with a method is seen in the following fragment:
Class A
{
Final void m1()
{
System.out.println("This is a final method.");
}
}
Class B extends A
{
Void m1()
{
// ERROR! Can't override.
System.out.println("Illegal!");
}
}
Java normally resolves method calls dynamically at runtime. This is referred to as late binding or dynamic binding. A call to one can be resolved at build time because final methods cannot be overridden. This is referred to as "early" or "static" binding.
Key takeaway
In Java, the keyword final is used to limit some functionality. The final keyword can be used to declare variables, methods, and classes.
Polymorphism can be defined as the ability to take different forms. It occurs when inheritance is used to have many classes that are related to each other.
Polymorphism most commonly used when a parent class reference is made to refer to a child class object.
Being one of the most important features of OOP, it must be supported by all languages based on OOP. Polymorphism in Java gives us the flexibility to use all the inherited properties of superclass to perform a task.
In real life, the simplest example to explain the concept of polymorphism is a person class. A single person can have different relationship with other person, like a mother, a daughter, a sister, a friend, an employee etc.
To better understand the concept of polymorphism we have to take a look at an example.
Consider a superclass named “Shapes” having a method name area(). The subclasses of this superclass can be Square, Rectangle, Triangle or any other shape. Using inheritance the subclass inherits the area() method also, but each shape has its own way of calculating area. Hence we can see that method name is same but it is used in different forms.
Class Shapes {
Public void area() {
System.out.println("Area of shape can be calculated as: \n");
}
}
Class Square extends Shapes {
Public void area() {
System.out.println("Area of Square is side * side ");
}
}
Class Rectangle extends Shapes {
Public void area() {
System.out.println("Area of Rectangle is base * height ");
}
}
Class Main {
Public static void main(String[] args) {
Shapes myShape = new Shapes(); // Create a Shapes object
Shapes mySquare = new Square(); // Create a Triangle object
Shapes myRectangle = new Rectangle(); // Create a Circle object
MyShape.area();
MySquare.area();
MyRectangle.area();
}
}
Output
Area of shape can be calculated as:
Area of Square is side * side
Area of Rectangle is base * height
Significance of Polymorphism in Java
The most significant use of polymorphism in Java is to write a method in different ways having multiple functionalities, with same method name.
Polymorphism helps to achieve consistency in a code.
Advantages of Polymorphism
- Code can be reusable in polymorphism, which means the classes that are already written can be used many times.
- We can use a single variable to store data values in multiple definition of methods. It will not change the value of a variable in the superclass, in fact allows storing subclass variable data also.
- Polymorphism allows lesser line of code, which helps the programmer to debug in case of error.
Types of polymorphism
Java supports two types of polymorphism:
- Compile time polymorphism
- Runtime polymorphism
Compile Time Polymorphism
It is also known as static polymorphism in Java. In this type, method call is made at compile time.
Compile type polymorphism is achieved through the concept of method overloading and operator overloading. However operator overloading is not supported in Java.
Method overloading can be defined as overloading of methods having same name i.e. when a class consist of multiple methods having same name but differs in the number, types, parameters and the return type of methods.
Java gives the flexibility to the user to create as many methods of same as long as it can be differentiate between them by the type and number of parameters.
Method overloading is explained in detail below.
Runtime Polymorphism
In Java, runtime polymorphism is also referred as Dynamic Binding or Dynamic Method Dispatch. In this process, at runtime we can call to an overridden method to process dynamically rather at compile time.
To implement the runtime polymorphism we us method overridden.
Method overridden happens when the child or subclass has a method with same definition as the parent or superclass, then that function overrides the function in the superclass.
In this process, a reference variable of a superclass is used to called an overridden method.
Dynamic binding
The method to be called is not determined by the compiler in dynamic binding. Dynamic binding is exemplified through overriding. Both the parent and child classes have the same approach for overriding.
Dynamic binding occurs when the type of an object is determined at run-time.
Example
Class Animal{
Void eat(){System.out.println("animal is eating...");}
}
Class Dog extends Animal{
Void eat(){System.out.println("dog is eating...");}
Public static void main(String args[]){
Animal a=new Dog();
a.eat();
}
}
Output
Output: dog is eating…
Because the instance of Dog is also an instance of Animal, the compiler cannot detect the object type in the previous example. As a result, the compiler only knows its basic type.
Key takeaway
Polymorphism can be defined as the ability to take different forms. It occurs when inheritance is used to have many classes that are related to each other.
In Java, method overriding is a technique through which a subclass or derived class can provide its own version of a method whose implementation is given by one its super class.
By doing this a subclass is defining a method having same name, same parameter, and same return type similar to method in the superclass. Then the method in the subclass is said to override the method in the superclass.
The concept of runtime polymorphism in Java can be implemented using Method overriding.
The next important question is which class method will be executed. So the answer is
- When an object of a parent class makes a call to method, then the parent class method will be executed.
- When an object of a child class makes a call to method, then the child class method will be executed.
Hence, the type of object used for referring determines which version of the method will be executed in the case of overridden method.
A simple example showing how overridden method are created and called.
//Parent class declaration
Class Parent{
Void display() //method defined in parent class
{
System.out.println(Method of parent class”);
}
}
//Child class declaration
Class Child extends Parent{
Void display() //child class method overrides parent class method
{
System.out.println(Method of child class”);
}
}
Class Demo{
Public static void main(String[] args)
{
Parent p = new Parent(); // object of parent class
Parent o = new Child(); // object of child class
p.display(); //reference made to parent class method by object p
o.display(); //reference made to child class method by object o
}
}
Output
Method of parent class
Method of child class
Rules for Method Overriding
- Overridden method must have same name and parameters.
- Method which is declared as final cannot be overridden.
- Static methods cannot be used to override.
- Overridden is not possible in private method.
- The return type of overriding method must be same.
- Constructors cannot be override.
- IS-A relationship must be fulfill in method overridden technique.
Key takeaway
In Java, method overriding is a technique through which a subclass or derived class can provide its own version of a method whose implementation is given by one its super class.
Dynamic binding is exemplified through overriding. Both the parent and child classes have the same approach for overriding.
Abstraction, according to the definition, is the ability to deal with ideas rather than occurrences. When it comes to email, for example, intricate information like what happens when you send an e-mail and the protocol your e-mail server utilises are hidden from the user. As a result, all you have to do to send an email is input the content, include the recipient's address, and click send.
Similarly, in Object-oriented programming, abstraction is the process of hiding implementation details from the user and simply providing functionality. To put it another way, the user will be given knowledge about what the object does rather than how it does it.
Abstract classes and interfaces are used in Java to achieve abstraction.
Abstract Classes
Abstract class is a type of class that has the abstract keyword in its declaration.
● Abstract classes may or may not contain abstract methods (public void get();).
● However, a class must be designated abstract if it has at least one abstract method.
● A class that has been declared abstract cannot be instantiated.
● You must inherit an abstract class from another class and supply implementations for the abstract methods in it in order to use it.
● You must supply implementations for all abstract methods in an abstract class if you inherit it.
Example
This section shows you how to use the abstract class. Simply use the abstract keyword before the class keyword in the class definition to create an abstract class.
/* File name: Employee.java */
Public abstract class Employee {
Private String name;
Private String address;
Private int number;
Public Employee(String name, String address, int number) {
System.out.println("Constructing an Employee");
This.name = name;
This.address = address;
This.number = number;
}
Public double computePay() {
System.out.println("Inside Employee computePay");
Return 0.0;
}
Public void mailCheck() {
System.out.println("Mailing a check to " + this.name + " " + this.address);
}
Public String toString() {
Return name + " " + address + " " + number;
}
Public String getName() {
Return name;
}
Public String getAddress() {
Return address;
}
Public void setAddress(String newAddress) {
Address = newAddress;
}
Public int getNumber() {
Return number;
}
}
Except for abstract methods, the Employee class is identical to a regular Java class. The class has three fields, seven methods, and one function Object() { [native code] }, but it is now abstract.
You may now attempt to instantiate the Employee class as follows:
/* File name : AbstractDemo.java */
Public class AbstractDemo {
Public static void main(String [] args) {
/* Following is not allowed and would raise error */
Employee e = new Employee("George W.", "Houston, TX", 43);
System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}
When you compile the above class, it gives you the following error −
Employee.java:46: Employee is abstract; cannot be instantiated
Employee e = new Employee("George W.", "Houston, TX", 43);
^
1 error
Inheriting the Abstract class
We may inherit the properties of the Employee class in the same way that we can inherit the properties of concrete classes in the following method:
Example
/* File name : Salary.java */
Public class Salary extends Employee {
Private double salary; // Annual salary
Public Salary(String name, String address, int number, double salary) {
Super(name, address, number);
SetSalary(salary);
}
Public void mailCheck() {
System.out.println("Within mailCheck of Salary class ");
System.out.println("Mailing check to " + getName() + " with salary " + salary);
}
Public double getSalary() {
Return salary;
}
Public void setSalary(double newSalary) {
If(newSalary >= 0.0) {
Salary = newSalary;
}
}
Public double computePay() {
System.out.println("Computing salary pay for " + getName());
Return salary/52;
}
}
You can't instantiate the Employee class here, but you can instantiate the Salary Class, and you can access all three fields and seven methods of the Employee class using this instance, as seen below.
/* File name : AbstractDemo.java */
Public class AbstractDemo {
Public static void main(String [] args) {
Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
System.out.println("Call mailCheck using Salary reference --");
s.mailCheck();
System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}
Output
Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0
Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.0
Abstract Methods
If you want a class to contain a method but the actual implementation of that method to be determined by child classes, designate the method as an abstract in the parent class.
● To declare a method abstract, use the abstract keyword.
● In the method declaration, the abstract keyword must come before the method name.
● There is no method body in an abstract method, only a method signature.
● An abstract method will have a semicolon (;) at the end instead of curly braces.
The abstract technique is demonstrated in the following example.
Example
Public abstract class Employee {
Private String name;
Private String address;
Private int number;
Public abstract double computePay();
// Remainder of class definition
}
Declaring a method abstract has two ramifications.
● It must be specified as abstract in the class that contains it.
● Any class that inherits the current class must either override or declare the abstract method.
Note that a descendant class must implement the abstract method at some point; otherwise, you'll wind up with a hierarchy of abstract classes that can't be created.
If the Salary class derives from the Employee class, the computePay() method should be implemented as shown below.
/* File name : Salary.java */
Public class Salary extends Employee {
Private double salary; // Annual salary
Public double computePay() {
System.out.println("Computing salary pay for " + getName());
Return salary/52;
}
// Remainder of class definition
}
Key takeaway
Abstraction, according to the definition, is the ability to deal with ideas rather than occurrences. When it comes to email, for example, intricate information like what happens when you send an e-mail and the protocol your e-mail server utilises are hidden from the user.
References:
- Programming in Java. Second Edition. Oxford Higher Education. (Sachin Malhotra/Saura V Choudhary)
- CORE JAVA For Beginners. (Rashmi Kanta Das), Vikas Publication
- JAVA Complete Reference (9th Edition) Herbert Schelidt.
- T. Budd, “Understanding Object- Oriented Programming with Java”, Pearson Education, Updated Edition (New Java 2 Coverage), 1999.