Unit 3:
Inheritance and interfaces
3.1 inheritance Basics
3.2 inheritance and constructors
3.3 super keyword
3.4 method overriding
3.5 polymorphism
3.6 dynamic binding
3.7 final keyword
3.8 abstract classes
3.9 access specifier
3.10 interfaces
Inheritance in Java
Inheritance in Java is a mechanism in which one object acquires all the
properties and behaviors of a parent object. It is an important part of OOPs (Object Oriented programming system).
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.
Inheritance
represents the IS-A relationship which is also known as a parent-child
relationship.
- For Method Overriding (so runtime polymorphism can be
achieved).
- For Code
Reusability.
AD
The syntax of Java Inheritance
- class Subclass-name extends Superclass-name
- {
- //methods and fields
- }
The extends
keyword indicates that you are making a new class that derives from an
existing class. The meaning of "extends" is to increase the
functionality.
In the
terminology of Java, a class which is inherited is called a parent or
superclass, and the new class is called child or subclass.
Java Inheritance Example
As displayed in
the above figure, Programmer is the subclass and Employee is the superclass.
The relationship between the two classes is Programmer IS-A Employee. It
means that Programmer is a type of Employee.
- class Employee{
- float salary=40000;
- }
- class Programmer extends Employee{
- int bonus=10000;
- public static void main(String args[]){
- Programmer p=new Programmer();
- System.out.println("Programmer salary is:"+p.salary);
- System.out.println("Bonus of Programmer is:"+p.bonus);
- }
- }
Programmer salary is:40000.0
Bonus of programmer is:10000
Types of inheritance in java
On the basis of
class, there can be three types of inheritance in java: single, multilevel and
hierarchical.
In java
programming, multiple and hybrid inheritance is supported through interface
only. We will learn about interfaces later.
Single Inheritance Example
When a class
inherits another class, it is known as a single inheritance. In the
example given below, Dog class inherits the Animal class, so there is the
single inheritance.
File:
TestInheritance.java
- 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 Example
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...
AD
Hierarchical Inheritance Example
When two or
more classes inherits a single class, it is known as hierarchical
inheritance. In the example given below, Dog and Cat classes inherits the
Animal class, so there is hierarchical inheritance.
AD
File:
TestInheritance3.java
- 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...
Constructors in Java
A constructor
in Java is similar to a method with a few differences. Constructor has the same
name as the class name. A constructor doesn't have a return type.
A Java program
will automatically create a constructor if it is not already defined in the
program. It is executed when an instance of the class is created.
A constructor
cannot be static, abstract, final or synchronized. It cannot be overridden.
Java has two
types of constructors:
- Default
constructor
- Parameterized
constructor
1. example of constructor in Single inheritance
In single level
inheritance, the constructor of the base class is executed first.
OrderofExecution1.java
- /* Parent Class */
- class ParentClass
- {
- /* Constructor */
- ParentClass()
- {
- System.out.println("ParentClass constructor executed.");
- }
- }
-
- /* Child Class */
- class ChildClass extends ParentClass
- {
- /* Constructor */
- ChildClass()
- {
- System.out.println("ChildClass constructor executed.");
- }
- }
-
- public class OrderofExecution1
- {
- /* Driver Code */
- public static void main(String ar[])
- {
- /* Create instance of ChildClass */
- System.out.println("Order of constructor execution...");
- new ChildClass();
- }
- }
Output:
Order of constructor execution...
ParentClass constructor executed.
ChildClass constructor executed.
In the above
code, after creating an instance of ChildClass the ParentClass
constructor is invoked first and then the ChildClass.
2. example of constructor in Multilevel inheritance
In multilevel
inheritance, all the upper class constructors are executed when an instance of
bottom most child class is created.
OrderofExecution2.java
- class College
- {
- /* Constructor */
- College()
- {
- System.out.println("College constructor executed");
- }
- }
-
- class Department extends College
- {
- /* Constructor */
- Department()
- {
- System.out.println("Department constructor executed");
- }
- }
-
- class Student extends Department
- {
- /* Constructor */
- Student()
- {
- System.out.println("Student constructor executed");
- }
- }
- public class OrderofExecution2
- {
- /* Driver Code */
- public static void main(String ar[])
- {
- /* Create instance of Student class */
- System.out.println("Order of constructor execution in Multilevel inheritance...");
- new Student();
- }
- }
Output:
Order of constructor execution in Multilevel
inheritance...
College constructor executed
Department constructor executed
Student constructor executed
In the above
code, an instance of Student class is created and it invokes the
constructors of College, Department and Student
accordingly.
3. example of same class constructor using this keyword
Here,
inheritance is not implemented. But there can be multiple constructors of a
single class and those constructors can be accessed using this keyword.
OrderofExecution3.java
- public class OrderofExecution3
- {
- /* Default constructor */
- OrderofExecution3()
- {
- this("CallParam");
- System.out.println("Default constructor executed.");
- }
- /* Parameterized constructor */
- OrderofExecution3(String str)
- {
- System.out.println("Parameterized constructor executed.");
- }
- /* Driver Code */
- public static void main(String ar[])
- {
- /* Create instance of the class */
- System.out.println("Order of constructor execution...");
- OrderofExecution3 obj = new OrderofExecution3();
- }
- }
Output:
Order of constructor execution...
Parameterized constructor executed.
Default constructor executed.
In the above
code, the parameterized constructor is called first even when the default
constructor is called while object creation. It happens because this
keyword is used as the first line of the default constructor.
AD
4. example of Calling superclass constructor using super
keyword
A child class
constructor or method can access the base class constructor or method using the
super keyword.
OrderofExecution4.java
- /* Parent Class */
- class ParentClass
- {
- int a;
- ParentClass(int x)
- {
- a = x;
- }
- }
-
- /* Child Class */
- class ChildClass extends ParentClass
- {
- int b;
- ChildClass(int x, int y)
- {
- /* Accessing ParentClass Constructor */
- super(x);
- b = y;
- }
- /* Method to show value of a and b */
- void Show()
- {
- System.out.println("Value of a : "+a+"\nValue of b : "+b);
- }
- }
-
- public class OrderofExecution4
- {
- /* Driver Code */
- public static void main(String ar[])
- {
- System.out.println("Order of constructor execution...");
- ChildClass d = new ChildClass(79, 89);
- d.Show();
- }
- }
Output:
Order of constructor execution...
Value of a : 79
Value of b : 89
In the above
code, the ChildClass calls the ParentClass
constructor using a super keyword that determines the order of
execution of constructors.
Super Keyword in Java
The super keyword in Java is a reference
variable which is used to refer immediate parent class object.
Whenever you create the instance of subclass, an instance
of parent class is created implicitly which is referred by super reference
variable.
Usage of Java super Keyword
- super can be used to refer immediate parent class instance
variable.
- super can be used to invoke immediate parent class method.
- super() can be used to invoke immediate parent class
constructor.
super example: real use
Let's see the real use of super keyword. Here, Emp class
inherits Person class so all the properties of Person will be inherited to Emp
by default. To initialize all the property, we are using parent class
constructor from child class. In such way, we are reusing the parent class
constructor.
- class Person{
- int id;
- String name;
- Person(int id,String name){
- this.id=id;
- this.name=name;
- }
- }
- class Emp extends Person{
- float salary;
- Emp(int id,String name,float salary){
- super(id,name);//reusing parent constructor
- this.salary=salary;
- }
- void display(){System.out.println(id+" "+name+" "+salary);}
- }
- class TestSuper5{
- public static void main(String[] args){
- Emp e1=new Emp(1,"ankit",45000f);
- e1.display();
- }}
Output:
1 ankit 45000
Method Overriding in Java
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).
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
Polymorphism in Java
Polymorphism in Java is a concept by which we can perform a single action in
different ways. Polymorphism is derived from 2 Greek words: poly and
morphs. The word "poly" means many and "morphs" means
forms. So polymorphism means many forms.
There are two types of polymorphism in Java: compile-time
polymorphism and runtime polymorphism. We can perform polymorphism in java by
method overloading and method overriding.
If you overload a static method in Java, it is the example
of compile time polymorphism. Here, we will focus on runtime polymorphism in
java.
Runtime Polymorphism in Java
Runtime polymorphism or Dynamic Method Dispatch is a process in which a
call to an overridden method is resolved at runtime rather than compile-time.
In this process, an overridden method is called through the
reference variable of a superclass. The determination of the method to be
called is based on the object being referred to by the reference variable.
Let's first understand the upcasting before Runtime
Polymorphism.
Upcasting
If the reference variable of Parent class refers to the
object of Child class, it is known as upcasting. For example:
- class A{}
- class B extends A{}
- A a=new B();//upcasting
For upcasting, we can use the reference variable of class
type or an interface type. For Example:
- interface I{}
- class A{}
- class B extends A implements I{}
Here, the relationship of B class would be:
B IS-A A
B IS-A I
B IS-A Object
Since Object is the root class of all classes in Java, so
we can write B IS-A Object.
Example of Java Runtime Polymorphism
In this example, we are creating two classes Bike and
Splendor. Splendor class extends Bike class and overrides its run() method. We
are calling the run method by the reference variable of Parent class. Since it
refers to the subclass object and subclass method overrides the Parent class
method, the subclass method is invoked at runtime.
Since method invocation is determined by the JVM not
compiler, it is known as runtime polymorphism.
- class Bike{
- void run(){System.out.println("running");}
- }
- class Splendor extends Bike{
- void run(){System.out.println("running safely with 60km");}
-
- public static void main(String args[]){
- Bike b = new Splendor();//upcasting
- b.run();
- }
- }
Output:
running safely with 60km.
Dynamic Polymorphism
Dynamic polymorphism is a process or mechanism in which a call to an overridden method
is to resolve at runtime rather than compile-time. It is also known as runtime
polymorphism or dynamic method dispatch. We can
achieve dynamic polymorphism by using the method
overriding.
In this process, an overridden method is called through a
reference variable of a superclass. The determination of the method to be
called is based on the object being referred to by the reference variable.
Properties of Dynamic Polymorphism
- It decides which method is to execute at runtime.
- It can be achieved through dynamic binding.
- It happens between different classes.
- It is required where a subclass object is assigned to a
super-class object for dynamic polymorphism.
- Inheritance involved in dynamic polymorphism.
AD
Method Overriding
It provides a specific implementation to a method that is
already present in the parent class. it is used to achieve run-time
polymorphism. Remember that, it is not possible to override the static
method. Hence, we cannot override the main() method also because it is a static
method.
Rules for Method Overriding
- The name of the method must be the same as the name of the
parent class method.
- The number of parameters and the types of parameters must be
the same as in the parent class.
- There must exist an IS-A relationship (inheritance).
We call an overridden method through a reference of the
parent class. The type of object decides which method is to be executed and it
is decided by the JVM
at runtime.
Example of Dynamic Polymorphism
In the following example, we have created two classes named
Sample and Demo. The Sample class is a parent
class and the Demo class is a child or derived
class. The child class is overriding the dispaly() method of
the parent class.
We have assigned the child class object to the parent class
reference. So, in order to determine which method would be called, the type of
the object would be decided by the JVM at run-time. It is the type of object
that determines which version of the method would be called (not the type of
reference).
Demo.java
- //parent class
- class Sample
- {
- //method of the parent class
- public void display()
- {
- System.out.println("Overridden Method");
- }
- }
- //derived or child class
- public class Demo extends Sample
- {
- //method of child class
- public void display()
- {
- System.out.println("Overriding Method");
- }
- public static void main(String args[])
- {
- //assigning a child class object to parent class reference
- Sample obj = new Demo();
- //invoking display() method
- obj.display();
- }
- }
Output:
Overriding Method
Example of Method Overriding
DynamicPolymorphismExample.java
- public class DynamicPolymorphismExample
- {
- public static void main(String args[])
- {
- //assigning a child class object to a parent class reference
- Fruits fruits = new Mango();
- //invoking the method
- fruits.color();
- }
- }
- //parent class
- class Fruits
- {
- public void color()
- {
- System.out.println("Parent class method is invoked.");
- }
- }
- //derived or child class that extends the parent class
- class Mango extends Fruits
- {
- //overrides the color() method of the parent class
- @Override
- public void color()
- {
- System.out.println("The child class method is invoked.");
- }
- }
Output:
The child class method is invoked.
Final Keyword In Java
The final keyword in java is used to restrict the
user. The java final keyword can be used in many context. Final can be:
- variable
- method
- class
The final keyword can be applied with the variables, a
final variable that have no value it is called blank final variable or
uninitialized final variable. It can be initialized in the constructor only.
The blank final variable can be static also which will be initialized in the
static block only. We will have detailed learning of these. Let's first learn
the basics of final keyword.
1) Java final variable
If you make any variable as final, you cannot change the
value of final variable(It will be constant).
Example of final variable
There is a final variable speedlimit, we are going to
change the value of this variable, but It can't be changed because final
variable once assigned a value can never be changed.
- class Bike9{
- final int speedlimit=90;//final variable
- void run(){
- speedlimit=400;
- }
- public static void main(String args[]){
- Bike9 obj=new Bike9();
- obj.run();
- }
- }//end of class
Output:Compile Time Error
2) Java final method
If you make any method as final, you cannot override it.
Example of final method
- class Bike{
- final void run(){System.out.println("running");}
- }
-
- class Honda extends Bike{
- void run(){System.out.println("running safely with 100kmph");}
-
- public static void main(String args[]){
- Honda honda= new Honda();
- honda.run();
- }
- }
Output:Compile Time Error
3) Java final class
If you make any class as final, you cannot extend it.
Example of final class
- final class Bike{}
-
- class Honda1 extends Bike{
- void run(){System.out.println("running safely with 100kmph");}
-
- public static void main(String args[]){
- Honda1 honda= new Honda1();
- honda.run();
- }
- }
Output:Compile Time Error
Abstract class in Java
A class which is declared with the abstract keyword is
known as an abstract class in Java.
It can have abstract and non-abstract methods (method with the body).
Before learning the Java abstract class, let's understand
the abstraction in Java first.
Abstraction in Java
Abstraction is a
process of hiding the implementation details and showing only functionality to
the user.
Another way, it shows only essential things to the user and
hides the internal details, for example, sending SMS where you type the text
and send the message. You don't know the internal processing about the message
delivery.
Abstraction lets you focus on what the object does
instead of how it does it.
Ways to achieve Abstraction
There are two ways to achieve abstraction in java
- Abstract class (0 to 100%)
- Interface (100%)
Abstract class in Java
A class which is declared as abstract is known as an abstract
class. It can have abstract and non-abstract methods. It needs to be
extended and its method implemented. It cannot be instantiated.
Points to Remember
- An abstract class must be declared with an abstract keyword.
- It can have abstract and non-abstract methods.
- It cannot be instantiated.
- It can have constructors and
static methods also.
- It can have final methods which will force the subclass not to
change the body of the method.
Example of abstract class
- abstract class A{}
Abstract Method in Java
A method which is declared as abstract and does not have
implementation is known as an abstract method.
Example of abstract method
- abstract void printStatus();//no method body and abstract
Example of Abstract class that has an abstract method
In this example, Bike is an abstract class that contains
only one abstract method run. Its implementation is provided by the Honda
class.
- abstract class Bike{
- abstract void run();
- }
- class Honda4 extends Bike{
- void run(){System.out.println("running safely");}
- public static void main(String args[]){
- Bike obj = new Honda4();
- obj.run();
- }
- }
running safely
Access Modifiers in Java
There are two types of modifiers in Java: access
modifiers and non-access modifiers.
The access modifiers in Java specifies the accessibility or
scope of a field, method, constructor, or class. We can change the access level
of fields, constructors, methods, and class by applying the access modifier on
it.
There are four types of Java access modifiers:
- Private:
The access level of a private modifier is only within the class. It cannot
be accessed from outside the class.
- Default:
The access level of a default modifier is only within the package. It
cannot be accessed from outside the package. If you do not specify any
access level, it will be the default.
- Protected:
The access level of a protected modifier is within the package and outside
the package through child class. If you do not make the child class, it
cannot be accessed from outside the package.
- Public:
The access level of a public modifier is everywhere. It can be accessed
from within the class, outside the class, within the package and outside
the package.
There are many non-access modifiers, such as static,
abstract, synchronized, native, volatile, transient, etc. Here, we are going to
learn the access modifiers only.
Understanding Java Access Modifiers
Let's understand the access modifiers in Java by a simple
table.
Access Modifier |
within class |
within package |
outside package by subclass only |
outside package |
Private |
Y |
N |
N |
N |
Default |
Y |
Y |
N |
N |
Protected |
Y |
Y |
Y |
N |
Public |
Y |
Y |
Y |
Y |
1) Private
The private access modifier is accessible only within the
class.
Simple example of private access modifier
In this example, we have created two classes A and Simple.
A class contains private data member and private method. We are accessing these
private members from outside the class, so there is a compile-time error.
- class A{
- private int data=40;
- private void msg(){System.out.println("Hello java");}
- }
-
- public class Simple{
- public static void main(String args[]){
- A obj=new A();
- System.out.println(obj.data);//Compile Time Error
- obj.msg();//Compile Time Error
- }
- }
Role of Private Constructor
If you make any class constructor private, you cannot
create the instance of that class from outside the class. For example:
- class A{
- private A(){}//private constructor
- void msg(){System.out.println("Hello java");}
- }
- public class Simple{
- public static void main(String args[]){
- A obj=new A();//Compile Time Error
- }
- }
Note: A class cannot be private or protected except nested
class.
2) Default
If you don't use any modifier, it is treated as default
by default. The default modifier is accessible only within package. It cannot
be accessed from outside the package. It provides more accessibility than
private. But, it is more restrictive than protected, and public.
Example of default access modifier
In this example, we have created two packages pack and
mypack. We are accessing the A class from outside its package, since A class is
not public, so it cannot be accessed from outside the package.
- //save by A.java
- package pack;
- class A{
- void msg(){System.out.println("Hello");}
- }
- //save by B.java
- package mypack;
- import pack.*;
- class B{
- public static void main(String args[]){
- A obj = new A();//Compile Time Error
- obj.msg();//Compile Time Error
- }
- }
In the above example, the scope of class A and its method
msg() is default so it cannot be accessed from outside the package.
3) Protected
The protected access modifier is accessible within
package and outside the package but through inheritance only.
The protected access modifier can be applied on the data
member, method and constructor. It can't be applied on the class.
It provides more accessibility than the default modifer.
Example of protected access modifier
AD
In this example, we have created the two packages pack and
mypack. The A class of pack package is public, so can be accessed from outside
the package. But msg method of this package is declared as protected, so it can
be accessed from outside the class only through inheritance.
- //save by A.java
- package pack;
- public class A{
- protected void msg(){System.out.println("Hello");}
- }
- //save by B.java
- package mypack;
- import pack.*;
-
- class B extends A{
- public static void main(String args[]){
- B obj = new B();
- obj.msg();
- }
- }
Output:Hello
4) Public
The public access modifier is accessible
everywhere. It has the widest scope among all other modifiers.
Example of public access modifier
- //save by A.java
-
- package pack;
- public class A{
- public void msg(){System.out.println("Hello");}
- }
- //save by B.java
-
- package mypack;
- import pack.*;
-
- class B{
- public static void main(String args[]){
- A obj = new A();
- obj.msg();
- }
- }
Output:Hello
Interface in Java
An interface in Java is a blueprint of a
class. It has static constants and abstract methods.
The interface in Java is a mechanism to achieve abstraction.
There can be only abstract methods in the Java interface, not method body. It
is used to achieve abstraction and multiple inheritance in Java.
In other words, you can say that interfaces can have
abstract methods and variables. It cannot have a method body.
Java Interface also represents the IS-A
relationship.
It cannot be instantiated just like the abstract class.
Since Java 8, we can have default and static
methods in an interface.
Since Java 9, we can have private methods
in an interface.
Why use Java interface?
There are mainly three reasons to use interface. They are
given below.
- It is used to achieve abstraction.
- By interface, we can support the functionality of multiple
inheritance.
- It can be used to achieve loose coupling.
How to declare an interface?
An interface is declared by using the interface keyword. It
provides total abstraction; means all the methods in an interface are declared
with the empty body, and all the fields are public, static and final by
default. A class that implements an interface must implement all the methods
declared in the interface.
Syntax:
- interface <interface_name>{
-
- // declare constant fields
- // declare methods that abstract
- // by default.
- }
No comments:
Post a Comment