0% found this document useful (0 votes)
101 views78 pages

Java

This document discusses inheritance in Java programming. It defines inheritance and the key terminology used, such as subclass, superclass, reusability, etc. It then explains the different types of inheritance in Java including single, multilevel, and hierarchical inheritance. It provides examples to illustrate each type of inheritance and discusses the advantages and disadvantages of using inheritance. The document also covers topics like member access, constructors, method overriding, abstract classes, and interfaces as they relate to inheritance.

Uploaded by

Anurag
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
101 views78 pages

Java

This document discusses inheritance in Java programming. It defines inheritance and the key terminology used, such as subclass, superclass, reusability, etc. It then explains the different types of inheritance in Java including single, multilevel, and hierarchical inheritance. It provides examples to illustrate each type of inheritance and discusses the advantages and disadvantages of using inheritance. The document also covers topics like member access, constructors, method overriding, abstract classes, and interfaces as they relate to inheritance.

Uploaded by

Anurag
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 78

Unit - 3

PROGRAMMING IN JAVA LAB


MCAS2330
School of Computing Science and Engineering
Master of Computer Applications
Prepared By
Dr. N.V.Kousik
Winter Session 2019 – 2020

School of Computing Science and Engineering


Version :1.0 Date:17-07-2019 Drafted by: Dr. N.V.Kousik
Unit – 3
Packages and Interface
Inheritance : basic ,Types of Inheritance, Member Access, Creating a Multilevel Hierarchy, When
Constructors Are Called Method Overriding ,Dynamic Method Dispatch ,Why Overridden Methods?,
Applying Method Overriding, Using Abstract Classes, Using final with Inheritance, Using final to Prevent
Overriding . Using final to Prevent Inheritance, Object Class, Packages and Interfaces.

Inheritance – Basic, Types of Inheritance,


Single Inheritance, Multiple Inheritances.
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.

Why use inheritance in java

 For Method Overriding (so runtime polymorphism can be achieved).


 For Code Reusability.

Terms used in Inheritance

 Class: A class is a group of objects which have common properties. It is a template or


blueprint from which objects are created.
 Sub Class/Child Class: Subclass is a class which inherits the other class. It is also called
a derived class, extended class, or child class.
 Super Class/Parent Class: Superclass is the class from where a subclass inherits the
features. It is also called a base class or a parent class.
 Reusability: As the name specifies, reusability is a mechanism which facilitates you to
reuse the fields and methods of the existing class when you create a new class. You can
use the same fields and methods already defined in the previous class.

The syntax of Java Inheritance

1. class Subclass-name extends Superclass-name


2. {
3. //methods and fields
4. }

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.

1. class Employee
2. {
3. float salary=40000;
4. }
5. class Programmer extends Employee
6. {
7. int bonus=10000;
8. public static void main(String args[])
9. {
10. Programmer p=new Programmer();
11. System.out.println("Programmer salary is:"+p.salary);
12. System.out.println("Bonus of Programmer is:"+p.bonus);
13. }
14. }
Output:
Programmer salary is: 40,000.0
Bonus of programmer is: 10,000
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.

When one class inherits multiple classes, it is known as multiple inheritance. For Example:

Single Inheritance Example

File: TestInheritance.java

1. class Animal{
2. void eat(){System.out.println("eating...");}
3. }
4. class Dog extends Animal{
5. void bark(){System.out.println("barking...");}
6. }
7. class TestInheritance{
8. public static void main(String args[]){
9. Dog d=new Dog();
10. d.bark();
11. d.eat();
12. }}

Output:

barking...
eating...

Multilevel Inheritance Example

File: TestInheritance2.java

1. class Animal
2. {
3. void eat() {System.out.println("eating...");}
4. }
5. class Dog extends Animal{
6. void bark() {System.out.println("barking...");}
7. }
8. class BabyDog extends Dog{
9. void weep() {System.out.println("weeping...");}
10. }
11. class TestInheritance2{
12. public static void main(String args[])
13. {
14. BabyDog d=new BabyDog();
15. d.weep();
16. d.bark();
17. d.eat();
18. }}

Output:

weeping...
barking...
eating...
Hierarchical Inheritance Example

File: TestInheritance3.java

1. class Animal{
2. void eat(){System.out.println("eating...");}
3. }
4. class Dog extends Animal{
5. void bark(){System.out.println("barking...");}
6. }
7. class Cat extends Animal{
8. void meow(){System.out.println("meowing...");}
9. }
10. class TestInheritance3{
11. public static void main(String args[]){
12. Cat c=new Cat();
13. c.meow();
14. c.eat();
15. //c.bark();//C.T.Error
16. }}

Output:

meowing...
eating.

Why multiple inheritance is not supported in java?


To reduce the complexity and simplify the language, multiple inheritance is not supported in
java.

Consider a scenario where A, B, and C are three classes. The C class inherits A and B classes. If
A and B classes have the same method and you call it from child class object, there will be
ambiguity to call the method of A or B class.

Since compile-time errors are better than runtime errors, Java renders compile-time error if you
inherit 2 classes. So whether you have same method or different, there will be compile time
error.
1. class A{
2. void msg(){System.out.println("Hello");}
3. }
4. class B{
5. void msg(){System.out.println("Welcome");}
6. }
7. class C extends A,B{//suppose if it were
8. public static void main(String args[]){
9. C obj=new C();
10. obj.msg();//Now which msg() method would be invoked?
11. }
12. }

Output: Compile Time Error

Advantages of Inheritance

Following are the advantages of using inheritance in programs:

 Reusability: The code and methods declared in the base class can be re used in the
derived class.
 Extensibility: Derived classes can be extended to provide new functionality of their own.
 Data Hiding: Base class can hide some of its data and code by making them private.
 Overriding: Derived classes can have methods with same signature as in base class. The
method in the derived class provides suitable functionality which might be different from
the methods available in the base class.

Disadvantages of Inheritance

Following are the disadvantages of using inheritance:

 More time taken for the control to reach the base class from derived classes when there
are several levels of inheritance.
 Tight coupling between the base class and derived class.
 Increase in maintenance time as changes done to base class may require changes to be
performed in the derived class.
Inheritance - Member Access
 Inheritance can be defined as the process of acquiring the properties of parent’s class by child
class.
 It provides the mechanism of code re-usability and represents IS-A relationship.
For example Bike is the super class (parent’s class) and Honda, Bajaj, TVS are the subclass
(child class, derived class). Honda, Bajaj and TVS have the property of Bike class.
 extends keyword is used for inheritance.
Syntax:
class Base
{
// code
}
class Derive extends Base
{
// code
}

Example: Sample program for inheritance

class SuperDemo
{
int result;
public void square(int a)
{
result = a * a;
System.out.println("The square of the "+a+" is: "+result);
}
}
public class SubDemo extends SuperDemo
{
public void cube(int a)
{
result = a * a * a;
System.out.println("The cube of the "+a+" is: "+result);
}
public static void main(String args[])
{
int a = 25;
SubDemo sub = new SubDemo();
sub.square(a);
sub.cube(a);
}
}

Output:
The square of the 25 is: 625
The cube of the 25 is: 15625
Types of inheritance

There are three types of inheritance in Java.


1. Single level
2. Multilevel inheritance
3. Hierarchical

Single Level Inheritance

When a class extends only one class, then it is called single level inheritance.

Fig: Single Level Inheritance

Syntax:
class A
{
//code
}
class B extends A
{
//code
}

Example: Sample program for single level inheritance

class Parent
{
public void m1()
{
System.out.println("Class Parent method");
}
}
public class Child extends Parent
{
public void m2()
{
System.out.println("Class Child method");
}
public static void main(String args[])
{
Child obj = new Child();
obj.m1();
obj.m2();
}
}

Output:
Class Parent method
Class Child method

Multilevel Inheritance

Multilevel inheritance is a mechanism where one class can be inherited from a derived class thereby
making the derived class the base class for the new class.

Fig: Multilevel Inheritance

Syntax:
class A
{
//code
}
class B extends A
{
//code
}
class C extends B
{
//code
}

Example: Sample program for multilevel inheritance

class Grand
{
public void m1()
{
System.out.println("Class Grand method");
}
}
class Parent extends Grand
{
public void m2()
{
System.out.println("Class Parent method");
}
}
class Child extends Parent
{
public void m3()
{
System.out.println("Class Child method");
}
public static void main(String args[])
{
Child obj = new Child();
obj.m1();
obj.m2();
obj.m3();
}
}

Output:
Class Grand method
Class Parent method
Class Child method

Hierarchical Inheritance

When one base class can be inherited by more than one class, then it is called hierarchical inheritance.

Fig: Hierarchical Inheritance

Syntax:
class A
{
// code
}
class B extends A
{
// code
}
class C extends A
{
//code
}

Example: Sample program for hierarchical inheritance

class A
{
public void m1()
{
System.out.println("method of Class A");
}
}
class B extends A
{
public void m2()
{
System.out.println("method of Class B");
}
}
class C extends A
{
public void m3()
{
System.out.println("method of Class C");
}
}
class D extends A
{
public void m4()
{
System.out.println("method of Class D");
}
}
public class MainClass
{
public void m5()
{
System.out.println("method of Class MainClass");
}
public static void main(String args[])
{
A obj1 = new A();
B obj2 = new B();
C obj3 = new C();
D obj4 = new D();
obj1.m1();
obj2.m1();
obj3.m1();
obj4.m1();
}
}

Output:
method of Class A
method of Class A
method of Class A
method of Class A

Multiple Inheritances

 In multiple inheritance, one derive class can extend more than one base class.
 Multiple inheritances are basically not supported by Java, because it increases the complexity of
the code.
 But they can be achieved by using interfaces.

Fig: Multiple Inheritance

Example: Sample program for multiple inheritance

class X
{
void display()
{
System.out.println("class X dispaly method ");
}
}
class Y
{
void display()
{
System.out.println("class Y display method ");
}
}
public class Z extends X,Y
{
public static void main(String args[])
{
Z obj=new Z();
obj.display();
}
}

Output:
Compile time error
Access Modifiers

Access modifiers are simply a keyword in Java that provides accessibility of a class and its member. They
set the access level to methods, variable, classes and constructors.

Types of access modifier

There are 4 types of access modifiers available in Java.


 public
 default
 protected
 private

public

The member with public modifiers can be accessed by any classes. The public methods, variables or class
have the widest scope.

Example: Sample program for public access modifier

public static void main(String args[])


{
// code
}

default

When we do not mention any access modifier, it is treated as default. It is accessible only within same
package.

Example: Sample program for default access modifier

int a = 25;
String str = "Java";
boolean m1()
{
return true;
}
protected

The protected modifier is used within same package. It lies between public and default access modifier. It
can be accessed outside the package but through inheritance only.
A class cannot be protected.

Example: Sample program for protected access modifier

class Employee
{
protected int id = 101;
protected String name = "Jack";
}
public class ProtectedDemo extends Employee
{
private String dept = "Networking";
public void display()
{
System.out.println("Employee Id : "+id);
System.out.println("Employee name : "+name);
System.out.println("Employee Department : "+dept);
}
public static void main(String args[])
{
ProtectedDemo pd = new ProtectedDemo();
pd.display();
}
}

Output:
Employee Id : 101
Employee name : Jack
Employee Department : Networking

Private

The private methods, variables and constructor are not accessible to any other class. It is the most
restrictive access modifier. A class except a nested class cannot be private.

Example: Sample program for private access modifier

public class PrivateDemo


{
private int a = 101;
private String s = "TutorialRide";
public void show()
{
System.out.println("Private int a = "+a+"\nString s = "+s);
}
public static void main(String args[])
{
PrivateDemo pd = new PrivateDemo();
pd.show();
System.out.println(pd.a+" "+pd.s);
}
}

Output:
Private int a = 101
String s = TutorialRide
101 TutorialRide

Table for Access Modifier


Access modifier In In Outside package by Outside package
class package subclass
public Yes Yes Yes No
protected Yes Yes Yes No
default Yes Yes No No
private Yes No No No

The super keyword in Java



super keyword is similar to this keyword in Java.

It is used to refer to the immediate parent class of the object.
Use of super keyword in Java
 super () calls the parent class constructor with no argument.
 super.methodname calls method from parents class.
 It is used to call the parents class variable.
Example: Sample program for invoking parents class constructor

class Animal
{
public Animal(String str)
{
System.out.println("Constructor of Animal: " + str);
}
}
class Lion extends Animal
{
public Lion()
{
super("super call Lion constructor");
System.out.println("Constructer of Lion.");
}
}
public class Test
{
public static void main(String[] a)
{
Lion lion = new Lion();
}
}

Output:
Constructor of Animal: super call from Lion constructor
Constructor of Lion.

Example: Sample program for calling parents class variable

class Base
{
int a = 50;
}
public class Derive extends Base
{
int a = 100;
void display()
{
System.out.println(super.a);
System.out.println(a);
}
public static void main(String[] args)
{
Derive derive = new Derive();
derive.display();
}
}

Output:
50
100

The final keyword in Java

The final keyword in Java indicates that no further modification is possible. Final can be Variable,
Method or Class

Final Variable

Final variable is a constant. We cannot change the value of final variable after initialization.

Example: Sample program for final keyword in Java

class FinalVarDemo
{
final int a = 10;
void show()
{
a = 20;
System.out.println("a : "+a);
}
public static void main(String args[])
{
FinalVarDemo var = new FinalVarDemo();
var.show();
}
}

Output:
Compile time error

Final Method

When we declare any method as final, it cannot be override.

Example: Sample program for final method in Java

class Animal
{
final void eat()
{
System.out.println("Animals are eating");
}
}
public class Dear extends Animal
{
void eat()
{
System.out.println("Dear is eating");
}
public static void main(String args[])
{
Dear dear = new Dear();
dear.eat();
}
}

Output:
Compile time error

Final Class

When a class is declared as a final, it cannot be extended.

Example: Sample program for final class in Java


final class Animal
{
void eat()
{
System.out.println("Animals are eating");
}
}
class Dear extends Animal
{
void eat()
{
System.out.println("Dear is eating");
}
public static void main(String args[])
{
Dear dear = new Dear();
dear.eat();
}
}

Output:
Compile time error
MULTILEVEL HIERARCHY IN JAVA PROGRAMMING
CREATING MULTILEVEL HIERARCHY

Creating multilevel hierarchy in java

In simple inheritance a subclass or derived class derives the properties from its parent class, but
in multilevel inheritance a subclass is derived from a derived class. One class inherits only single
class. Therefore, in multilevel inheritance, every time ladder increases by one. The lower most
class will have the properties of all the super classes’.

It is common that a class is derived from another derived class. The class student serves as a base
class for the derived class marks, which in turn serves as a base class for the derived class
percentage. The class marks is known as intermediates base class since it provides a link for the
inheritance between student and percentage. The chain is known as inheritance path. When this
type of situation occurs, each subclass inherits all of the features found in all of its super classes.
In this case, percentage inherits all aspects of marks and student.

Example for multilevel hierarchy:

class student
{
int rollno;
String name;
student(int r, String n)
{
rollno = r;
name = n;
}
void dispdatas()
{
System.out.println("Rollno = " + rollno);
System.out.println("Name = " + name);
}
}

class marks extends student


{
int total;
marks(int r, String n, int t)
{
super(r,n); //call super class (student) constructor
total = t;
}
void dispdatam()
{
dispdatas(); // call dispdatas of student class
System.out.println("Total = " + total);
}
}

class percentage extends marks


{
int per;

percentage(int r, String n, int t, int p)


{
super(r,n,t); //call super class(marks) constructor
per = p;
}
void dispdatap()
{
dispdatam(); // call dispdatam of marks class
System.out.println("Percentage = " + per);
}
}
class Multi_Inhe
{
public static void main(String args[])
{
percentage stu = new percentage(102689, "RATHEESH", 350, 70); //call constructor
percentage
stu.dispdatap(); // call dispdatap of percentage class
}
}

Output:
Rollno = 102689
Name = RATHEESH
Total = 350
Percentage = 70

When Constructors Are Called Method Overriding


When Constructors Are Called
When a class hierarchy is created, in what order are the constructors for the classes that make up
the hierarchy called? For example, given a subclass called B and a superclass called A, is A’s
constructor called before B’s, or vice versa? The answer is that in a class hierarchy, constructors
are called in order of derivation, from superclass to subclass. Further, since super( ) must be the
first statement executed in a subclass’ constructor, this order is the same whether or not super( )
is used. If super( ) is not used, then the default or parameterless constructor of each superclass
will be executed. The following program illustrates when constructors are executed:
// Demonstrate when constructors are called.
// Create a super class.
class A
{
A() {
System.out.println("Inside A's constructor.");
}
}
// Create a subclass by extending class A.
class B extends A {
B() {
System.out.println("Inside B's constructor.");
}
}
// Create another subclass by extending B.
class C extends B {
C() {
System.out.println("Inside C's constructor.");
}
}
class CallingCons {
public static void main(String args[]) {
THE JAVAC c = new C();
}
}
The output from this program is shown here:
Inside A’s constructor
Inside B’s constructor
Inside C’s constructor

As you can see, the constructors are called in order of derivation. If you think about it, it makes
sense that constructors are executed in order of derivation. Because a superclass has no
knowledge of any subclass, any initialization it needs to perform is separate from and possibly
prerequisite to any initialization performed by the subclass. Therefore, it must be executed first.
Method Overriding
In a class hierarchy, when a method in a subclass has the same name and type signature as a
method in its superclass, then the method in the subclass is said to override the method in the
superclass. When an overridden method is called from within a subclass, it will always refer to
the version of that method defined by the subclass. The version of the method defined by the
superclass will be hidden. Consider the following:
// Method overriding.
class A {
int i, j;
A(int a, int b) {
i = a;
j = b;
}
// display i and j
void show()
{
System.out.println("i and j: " + i + " " + j);
}
}
class B extends A
{
THE J int k;
B(int a, int b, int c) {
super(a, b);
k = c;
}
// display k – this overrides show() in A
void show() {
System.out.println("k: " + k);
}
}
class Override
{
public static void main(String args[]) {
B subOb = new B(1, 2, 3);
subOb.show(); // this calls show() in B
}
}
The output produced by this program is shown here:
k: 3
When show( ) is invoked on an object of type B, the version of show( ) defined within B is used.
That is, the version of show( ) inside B overrides the version declared in A. If you wish to access
the superclass version of an overridden function, you can do so by using super. For example, in
this version of B, the superclass version of show( ) is invoked within the subclass’ version. This
allows all instance variables to be displayed.
class B extends A {
int k;
B(int a, int b, int c)
{
super(a, b);
k = c;
}
void show()
{
super.show(); // this calls A's show()
System.out.println("k: " + k);
}
}
If you substitute this version of A into the previous program, you will see the following output:
i and j: 1 2
k: 3
Here, super.show( ) calls the superclass version of show( ). Method overriding occurs only when
the names and the type signatures of the two methods are identical. If they are not, then the two
methods are simply overloaded. For example, consider this modified version of the preceding
example:
// Methods with differing type signatures are overloaded – not
// overridden.
class A {
int i, j;
A(int a, int b) {
i = a;
j = b;
}
// display i and j
void show()
{
System.out.println("i and j: " + i + " " + j);
}
}
// Create a subclass by extending class A.
class B extends A {
int k;
B(int a, int b, int c)
{
super(a, b);
k = c;
THE JA}
// overload show()
void show(String msg)
{
System.out.println(msg + k);
}
}
class Override {
public static void main(String args[])
{
B subOb = new B(1, 2, 3);
subOb.show("This is k: "); // this calls show() in B
subOb.show(); // this calls show() in A
}
}

The output produced by this program is shown here:


This is k: 3
i and j: 1 2
The version of show( ) in B takes a string parameter. This makes its type signature different from
the one in A, which takes no parameters. Therefore, no overriding (or name hiding) takes place.
Dynamic Method Dispatch
While the examples in the preceding section demonstrate the mechanics of method overriding,
they do not show its power. Indeed, if there were nothing more to method overriding than a name
space convention, then it would be, at best, an interesting curiosity, but of little real value.
However, this is not the case. Method overriding forms the basis for one of Java’s most powerful
concepts: dynamic method dispatch.
Dynamic method dispatch is the mechanism by which a call to an overridden method is resolved
at run time, rather than compile time. Dynamic method dispatch is important because this is how
Java implements run-time polymorphism.
Let’s begin by restating an important principle: a superclass reference variable can refer to a
subclass object.
Java uses this fact to resolve calls to overridden methods at run time. Here is how. When an
overridden method is called through a superclass reference, Java determines which version of
that method to execute based upon the type of the object being referred to at the time the call
occurs. Thus, this determination is made at run time. When different types of objects are referred
to, different versions of an overridden method will be called. In other words, it is the type of the
object being referred to (not the type of the reference variable) that determines which version of
an overridden method will be executed. Therefore, if a superclass contains a method that is
overridden by a subclass, then when different types of objects are referred to through a
superclass reference variable, different versions of the method are executed. Here is an example
that illustrates dynamic method dispatch:
// Dynamic Method Dispatch
class A
{
void callme()
{
System.out.println("Inside A's callme method");
}
}
class B extends A
{
// override callme()
void callme()
{
System.out.println("Inside B's callme method");
}
}
class C extends A
{
// override callme()
void callme()
{
System.out.println("Inside C's callme method");
}
}

class Dispatch
{
public static void main(String args[])
{
A a = new A(); // object of type A
B b = new B(); // object of type B
C c = new C(); // object of type C
A r; // obtain a reference of type A
r = a; // r refers to an A object
r.callme(); // calls A's version of callme
r = b; // r refers to a B object
r.callme(); // calls B's version of callme
HE JAVA LANGUr = c; // r refers to a C object
r.callme(); // calls C's version of callme
}
}

The output from the program is shown here:


Inside A’s callme method
Inside B’s callme method
Inside C’s callme method
This program creates one superclass called A and two subclasses of it, called B and C.
Subclasses B and C override callme( ) declared in A. Inside the main( ) method, objects of type
A, B, and C are declared. Also, a reference of type A, called r, is declared.
The program then assigns a reference to each type of object to r and uses that reference to invoke
callme( ). As the output shows, the version of callme( ) executed is determined by the type of
object being referred to at the time of the call. Had it been determined by the type of the
reference variable, r, you would see three calls to A’s callme( ) method.

Inheritance with SUPER

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
1. super can be used to refer immediate parent class instance variable.
2. super can be used to invoke immediate parent class method.
3. super() can be used to invoke immediate parent class constructor.

1) super is used to refer immediate parent class instance variable.

We can use super keyword to access the data member or field of parent class. It is used if parent
class and child class have same fields.
1. class Animal{
2. String color="white";
3. }
4. class Dog extends Animal{
5. String color="black";
6. void printColor( ){
7. System.out.println(color);//prints color of Dog class
8. System.out.println(super.color);//prints color of Animal class
9. }
10. }
11. class TestSuper1{
12. public static void main(String args[]){
13. Dog d=new Dog();
14. d.printColor();
15. }}
Output:
black
white

In the above example, Animal and Dog both classes have a common property color. If we print
color property, it will print the color of current class by default. To access the parent property,
we need to use super keyword.

2) super can be used to invoke parent class method


The super keyword can also be used to invoke parent class method. It should be used if subclass
contains the same method as parent class. In other words, it is used if method is overridden.
1. class Animal{
2. void eat(){System.out.println("eating...");}
3. }
4. class Dog extends Animal{
5. void eat(){System.out.println("eating bread...");}
6. void bark(){System.out.println("barking...");}
7. void work(){
8. super.eat();
9. bark();
10. }
11. }
12. class TestSuper2{
13. public static void main(String args[]){
14. Dog d=new Dog();
15. d.work();
16. }}
Output:
eating...
barking...

In the above example Animal and Dog both classes have eat() method if we call eat() method
from Dog class, it will call the eat() method of Dog class by default because priority is given to
local.

To call the parent class method, we need to use super keyword.

3) super is used to invoke parent class constructor.


The super keyword can also be used to invoke the parent class constructor. Let's see a simple
example:

1. class Animal{
2. Animal(){System.out.println("animal is created");}
3. }
4. class Dog extends Animal{
5. Dog(){
6. super();
7. System.out.println("dog is created");
8. }
9. }
10. class TestSuper3{
11. public static void main(String args[]){
12. Dog d=new Dog();
13. }}
Output:
animal is created
dog is created

Super Keyword:

Whenever a sub class needs to refer to its immediate super class, we can use the super keyword.

Super has two general forms


• The first calls the super class constructor.

• The second is used to access a member of the super class that has been hidden by a member
of a sub class
Syntax:

A sub class can call a constructor defined by its super class by use of the following form of
super.

super(arg-list);

here arg-list specifies any arguments needed by the constructor in the super class .

The second form of super acts like a ―this‖ keyword.


The difference between ―this and super is that

―this is used to refer the current object whereas the super is used to refer to the super class.

The usage has the following general Form: super.member;

Example: Class x {
int a;
x() { a=0; }
void display() { System.out.println(a); }
}

class y extends x
{
int b;
y() { super(); b=1; }

Void display()
{
Super.display();
System.out.println(b);
}
}
class super_main
{
Public static void main(String args[])
{
y y1=new y();
y1.display();
}
}
JAVA SUPER-CLASS CONSTRUCTORS

 A constructor can invoke a super-class constructor using the method call super().
 You must support the super() method with appropriate arguments to select the desired
super-class constructor.
 The special call to super() must appear as the first statement in your delegating
constructor.
 Making super() call to a super-class constructors from other methods is illegal.

Super-class Constructor example:


class Person {
private int age;
private String name;

public Person(int age, String name) {


this.age = age;
this.name = name;
}

@Override
public String toString() {
return ("My name is " + name
+ " and I am " + age + " years old.");
}
}

class Doctor extends Person {


private String specialty;
Doctor(int age, String name, String specialty) {
// This is a call to the Person constructor with two parameters
super(age, name);
this.specialty = specialty;
}

@Override
public String toString() {
return super.toString() + " My profession is " + specialty;
}
}

public class SuperDemo {


public static void main(String args[]) {
Person peter = new Person(45, "Peter");
System.out.println(peter);
Doctor fred = new Doctor(46, "Fred", "dermatologist");
System.out.println(fred);
}
}
The result of this is:

My name is Peter and I am 45 years old.


My name is Fred and I am 46 years old. My profession is dermatologist

Applying Method Overriding, Using Abstract Classes, Using final


with Inheritance, Using final to Prevent Overriding

Java final Method: final keyword can be applied to methods apart variables and classes. The
main advantage of declaring a method final is to prevent subclass to override.
Let us go through a simple program on final method.
class Test
{
public final void display() // it is final method and cannot be overridden
{
System.out.println("From super class final display() method");
}
public void show() // it is non-final method and can be overridden
{
System.out.println("From super class non-final show() method");
}
}
public class Demo extends Test
{
// public void display() { } // gives error, see the next screenshot
public void show()
{
System.out.println("From subclass show() method");
}
public static void main(String args[])
{
Demo d1 = new Demo();
d1.display(); // calls super class display()
d1.show(); // calls subclass show(); see the next screenshot
}
}
1. Screenshot when the above example is executed
2. Screenshot when the comment is removed in subclass for public void display()

From above error message, you can understand that Java does not permit to override final
methods.

Why final methods cannot be overridden?

Salient points to note with final methods


1. Programmer declares a method as final in a class to prevent any subclass to override it.
This is done by the Programmer when he would like to fix the behaviour of a method (else,
it can be changed by subclass by overriding).
2.
There is a small discussion exists whether declaring a method final increases the
performance or efficiency.
A. Some Programmers say, does not increase because the method is loaded at runtime and
thereby compilers cannot make any inline efficiency implementation.
B. Every opportunity exists for the compiler to make final methods inline as compiler is
well aware of the method is final (at compile time itself). To increase the performance,
the final methods can be put inline or place in a cache as compiler knows very well
they cannot be changed in entire life time and whole application.JRE and JIT are
efficiently designed to do so.
3. Making a method final is an indication to compiler not to allow method overriding.
4. A final method cannot be hidden from subclass. That i, subclass cannot override, but can
make use of it as it is visible from subclass. This is where final method differs from static
method.
5. final method prevents subclass to change the behaviour of super class
method unexpectedly where the code is sensitive and crucial with some fixed functionality.
Final methods are so designed to give complete functionality.
6. A final method is deemed to be tried and tested so that subclass can use it straight away.
7. Make method final for when authentication and authorization code is final and should never
be altered.
8. Inherited class cannot override the super class final method because the meaning and
purpose is not to override.
9. It is a compile-time error if the final method is overridden.
10. You cannot hide final methods but you can hide private methods. This is where, final
differs with private.
11. In the Template design pattern, template methods are declared final.
12. No meaning to make a private method final also. There is no added advantage.
13. final methods cannot be overridden but can be overloaded.
14. final methods can be inherited. Can be called with subclass object.
15. abstract methods cannot be final and an abstract class cannot be final.
16. A constructor cannot be final as constructor is not inherited.
17. final methods are static binded (at compile time).

Finally, the ultimate purpose of final is to prevent overriding by subclass.

Using final with Inheritance

The keyword final has three uses. First, it can be used to create the equivalent of a named constant. This
use was described in the preceding chapter. The other two uses of final apply to inheritance. Both are
examined here.

Using final to Prevent Overriding

While method overriding is one of Java’s most powerful features, there will be times when you will want
to prevent it from occurring. To disallow a method from being overridden, specify final as a modifier at
the start of its declaration. Methods declared as final cannot be overridden. The following fragment
illustrates final:
class A {

final void meth() {

System.out.println("This is a final method.");

class B extends A {

void meth() { // ERROR! Can't override.

System.out.println("Illegal!");

Because meth( ) is declared as final, it cannot be overridden in B. If you attempt to do so, a compile-time error will
result. Methods declared as final can sometimes provide a performance enhancement: The compiler is free to inline
calls to them because it “knows” they will not be overridden by a subclass. When a small final method is called, often
the Java compiler can copy the bytecode for the subroutine directly inline with the compiled code of the calling
method, thus eliminating the costly overhead associated with a method call. Inlining is only an option with final
methods. Normally, Java resolves calls to methods dynamically, at run time. This is called late binding. However,
since final methods cannot be overridden, a call to one can be resolved at compile time. This is called early binding.

Using final to Prevent Inheritance

Sometimes you will want to prevent a class from being inherited. To do this, precede the class
declaration with final. Declaring a class as final implicitly declares all of its methods as final, too. As you
might expect, it is illegal to declare a class as both abstract and final since an abstract class is incomplete
by itself and relies upon its subclasses to provide complete implementations.

Here is an example of a final class:


final class A {

// ...
}

// The following class is illegal.

class B extends A { // ERROR! Can't subclass A

// ...

As the comments imply, it is illegal for B to inherit A since A is declared as final.

The Object Class

There is one special class, Object, defined by Java. All other classes are subclasses of Object. That is,
Object is a superclass of all other classes. This means that a reference variable of type Object can refer
to an object of any other class. Also, since arrays are implemented as classes, a variable of type Object
can also refer to any array. Object defines the following methods, which means that they are available in
every object.

The methods getClass( ), notify( ), notifyAll( ), and wait( ) are declared as final.You may override the
others. These methods are described elsewhere in this book. However, notice two methods now:
equals( ) and toString( ). The equals( ) method compares the contents of two objects. It returns true if
the objects are equivalent, and false otherwise. The toString( ) method returns a string that contains a
description of the object on which it is called. Also, this method is automatically called when an object is
output using println( ).

Using final with Inheritance


The keyword final has three uses. First, it can be used to create the equivalent of a named
constant. This use was described in the preceding chapter. The other two uses of final apply
to inheritance. Both are examined here.

Using final to Prevent Overriding

While method overriding is one of Java's most powerful features, there will be times when
you will want to prevent it from occurring. To disallow a method from being overridden,
specify final as a modifier at the start of its declaration. Methods declared as final cannot
be overridden. The following fragment illustrates final:

class A {
final void meth() {
System.out.println("This is a final method.");
}
}
class B extends A {
void meth() { // ERROR! Can't override.
System.out.println("Illegal!");
}
}

Because meth( ) is declared as final, it cannot be overridden in B.


If you attempt to do so, compile-time error will result.Methods declared as final can
sometimes provide a performance enhancement: The compiler is free to inline calls to them because
it "knows" they will not be overridden by a subclass. When small final method is called, often the
Java compiler can copy the bytecode for the subroutine directly inline with the compiled code of
the calling method, thus eliminating the costly overhead associated with a method call. Inlining is only an
option with final methods. Normally, Java resolves calls to methods dynamically, at run time. This
is called late binding. However, since final methods cannot be overridden, a call to one can be resolved
at compile time. This is called early binding.

Using Abstract Classes


Abstract Classes
There are situations in which you will want to define a superclass that declares the structure of a
given abstraction without providing a complete implementation of every method. That is,
sometimes you will want to create a superclass that only defines a generalized form that will be
shared by all of its subclasses, leaving it to each subclass to fill in the details. Such a class
determines the nature of the methods that the subclasses must implement. One way this situation
can occur is when a superclass is unable to create a meaningful implementation for a method.
This is the case with the class Figure used in the preceding example. The definition of area( ) is
simply a placeholder. It will not compute and display the area of any type of object. As you will
see as you create your own class libraries, it is not uncommon for a method to have no
meaningful definition in the context of its superclass. You can handle this situation two ways.
One way, as shown in the previous example, is to simply have it report a warning message.
While this approach can be useful in certain situations—such as debugging—it is not usually
appropriate. You may have methods which must be overridden by the subclass in order for the
subclass to have any meaning. Consider the class Triangle. It has no meaning if area( ) is not
defined. In this case, you want some way to ensure that a subclass does, indeed, override all
necessary methods. Java’s solution to this problem is the abstract method.
You can require that certain methods be overridden by subclasses by specifying the abstract
type modifier. These methods are sometimes referred to as subclasser responsibility because
they have no implementation specified in the superclass. Thus, a subclass must override them—it
cannot simply use the version defined in the superclass. To declare an abstract method, use this
general form:
abstract type name(parameter-list);
As you can see, no method body is present. Any class that contains one or more abstract methods
must also be declared abstract. To declare a class abstract, you simply use the abstract keyword
in front of the class keyword at the beginning of the class declaration. There can be no objects of
an abstract class. That is, an abstract class cannot be directly instantiated with the new operator.
Such objects would be useless, because an abstract class is not fully defined. Also, you cannot
declare abstract constructors, or abstract static methods. Any subclass of an abstract class must
either implement all of the abstract methods in the superclass, or be itself declared abstract.
Here is a simple example of a class with an abstract method, followed by a class which
implements that method:JAVA LANGUAGE
// A Simple demonstration of abstract.
abstract class A
{
abstract void callme();
// concrete methods are still allowed in abstract classes

void callmetoo()
{
System.out.println("This is a concrete method.");
}
}
class B extends A
{
void callme()
{
System.out.println("B's implementation of callme.");
}
}
class AbstractDemo
{
public static void main(String args[])
{
B b = new B();
b.callme();
b.callmetoo();
}
}
Notice that no objects of class A are declared in the program. As mentioned, it is not possible to
instantiate an abstract class. One other point: class A implements a concrete method called
callmetoo( ). This is perfectly acceptable. Abstract classes can include as much implementation
as they see fit. Although abstract classes cannot be used to instantiate objects, they can be used to
create object references, because Java’s approach to run-time polymorphism is implemented
through the use of superclass references. Thus, it must be possible to create a reference to an
abstract class so that it can be used to point to a subclass object.
You will see this feature put to use in the next example.
Using an abstract class, you can improve the Figure class shown earlier. Since there is no
meaningful concept of area for an undefined two-dimensional figure, the following version of the
program declares area( ) as abstract inside Figure. This, of course, means that all classes derived
from Figure must override area( ).
// Using abstract methods and classes.
abstract class Figure
{
double dim1;
double dim2;
Figure(double a, double b)
{
dim1 = a;
dim2 = b;
}
// area is now an abstract method
abstract double area();
}
class Rectangle extends Figure
{
Rectangle(double a, double b)
{
super(a, b);
}

// override area for rectangle


double area()
{
System.out.println("Inside Area for Rectangle.");
return dim1 * dim2;
}
}
class Triangle extends Figure
{
Triangle(double a, double b)
{
super(a, b);
}
// override area for right triangle
double area()
{
System.out.println("Inside Area for Triangle.");
return dim1 * dim2 / 2;
}
}
class AbstractAreas
{
public static void main(String args[])
{
// Figure f = new Figure(10, 10); // illegal now
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Figure figref; // this is OK, no object is created
figref = r;
System.out.println("Area is " + figref.area());
figref = t;
System.out.println("Area is " + figref.area());
}
}

As the comment inside main( ) indicates, it is no longer possible to declare objects of type
Figure, since it is now abstract. And, all subclasses of Figure must override area( ). To prove
this to yourself, try creating a subclass that does not override area( ). You will receive a
compile-time error. Although it is not possible to create an object of type Figure, you can create
a reference variable of type Figure.
The variable figref is declared as a reference to Figure, which means that it can be used to refer
to an object of any class derived from Figure. As explained, it is through superclass reference
variables that overridden methods are resolved at run time.
Why Object is Super Class in Java?
java.lang.Object class is the super base class of all Java classes. Every other Java classes
descends from Object.

In Mathematics, an axiom is a starting point of reasoning using which other statement can be
logically derived. The concept of Object class as super class of all classes in Java looks similar to
it.

It is not an explicit requirement forced on the developer. If a class is declared without extending
another class then it will implicitly extend Object class. This is taken care of by the JVM. This is
not applicable for the interfaces. A Java interface does not extends the Object.
Following could be the reasons for this design decision,
 By having the Object as the super class of all Java classes, without knowing the type we
can pass around objects using the Object declaration.
 Before generics was introduced, imagine the state of heterogeneous Java collections. A
collection class like ArrayList allows to store any type of classes. It was made possible
only by Object class hierarchy.
 The other reason would be to bring a common blueprint for all classes and have some list
of functions same among them. I am referring to methods like hashCode(), clone(),
toString() and methods for threading which is defined in Object class.
This concept cannot be generalized to all object oriented programming (OOPS) languages. For
instance, in C++ there is no such super class of all classes.

Super class of String, Object, Class


Following program shows
1. the super class of String class.
2. the super class of Object class
3. the super class of Class class
package com.javapapers.java;
public class SuperClass {
public static void main(String... args) {
String str = new String("Hi");
Class strClass = str.getClass();
System.out.println("Super class of String: " + strClass.getSuperclass());

Object obj = new Object();


Class objClass = obj.getClass();
System.out.println("Super class of Object: " + objClass.getSuperclass());

Class classClass = objClass.getClass();


System.out.println("Super class of Class: "+ classClass.getSuperclass());
}
}
Output
Super class of String: class java.lang.Object
Super class of Object: null
Super class of Class: class java.lang.Object
https://javapapers.com/java/why-object-is-super-class-in-java/

Object Class
 Object class is super class (or) base class for all the java classes. Every java class Extends
Object class means every java class is subclass to the Object class , without Object class we
can’t create any java class.

 Object class is available under java.lang package.


package com.sdj;
class A
{
public static void main(String[ ] args)
{
System.out.println("Hello World!");
}
}
The above program has been changed into the following manner after compilation.
package com.sdj;
class A extends Object
{
A( )
{
-----------
------------
}
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}

B.java
package com.sdj;
class A
{
String s="Galgotias";
}
class B
{
public static void main(String[] args)
{
System.out.println("Hello World!");
A a1=new A();
System.out.println(a1);
/*here a1.toString( ) will be called during the compilation instead of a1*/
}
}

Inside object class toString( ) is as follows:


public String toString()
{
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

B.java
package com.sdj;
class A extends Object
{
A( )
{
-----------------
-----------------
}
String s="Galgotias Universtiy";
}
class B extends Object
{
B( )
{
-----------------
-----------------
}
public static void main(String[] args)
{
System.out.println("Hello World!");
A a1=new A();
System.out.println(a1);
}
}

Overriding toString( ):
 By default toString( ) will return the fully qualified class name along with the memory address in
hexadecimal format.
 Whenever we call the derived type object (or) pass the derived object as input parameter to
System.Out.println( derived object ) then it will call automatically toString( ) during
compilation .
Example 2:
Before Overriding toString():
package com.sdj;
class Person
{
String name;
int age;
public Person(String name,int age)
{
this.age=age;
this.name=name;
}
}
public class OverrideToStringDemo
{
public static void main(String[] args)
{
Person p=new Person("Praveen",24);
System.out.println(p);
}
}
Output:

com.sdj.Person@82ba41
After Overriding toString():
package com.sdj;
class Person
{
String name;
int age;
public Person(String name,int age)
{
this.age=age;
this.name=name;
}
public String toString()
{
return"The Name of the Person:"+this.name+","+"The age of the person is:"+this.age;
}
}
public class OverrideToStringDemo
{
public static void main(String[] args)
{
Person p=new Person("Praveen",24);
System.out.println(p);
}
}

Output:
The Name of the Person: Praveen, The age of the person is:24
By overriding toString( ) method we can get desired value rather than the memory
address in hexadecimal format as described in the program.

Example for the comparing two Objects:


package com.sdj;
class Person
{
String name;
int age;
public Person(String name,int age)
{
this.age=age;
this.name=name;
}
public String toString()
{
return"The Name of the Person:"+this.name+","+"The age of the person is:"+this.age;
}
}
public class OverrideToStringDemo
{
public static void main(String[] args)
{
Person p1=new Person("Praveen",24);
System.out.println(p1);
Person p2=new Person("Praveen",24);
System.out.println(p1==p2);
Person p3=new Person("Sujata",23);
Person p4=new Person("Sujata",23);
System.out.println(p3==p4);
}
}
Output:

The Name of the Person:Praveen,The age of the person is:24


false
false
Explanation:

 In the above program p1 ,p2 objects and p3 , p4 objects content type is same but the
output of p1==p2 and p3==p4 is false.
 Because Equals operator will compare two Objects based on the memory location but not
based on the content of the object.
 Two objects have two different memory addresses.

Memory manage for the comparing two Objects

equals() in Object Class


 According to Object class, equals( ) act unlike equals operator i.e.( ==). It will compare two
similar objects and return output as Boolean value.
 If both objects are pointing to the same memory location like p1==p2 then the output is true else
false i.e. p1==p3.

Syntax of equals method :

public boolean equals(Object obj)


{
return (this.hashCode( ) == obj.hashCode( ));
}

Before overriding equals( ):


 Before overriding ,equals( ) will act unlike equals operator as described in below program.
Example 1:
package com.sdj;
class Person
{
String name;
int age;
public Person(String name,int age)
{
this.age=age;
this.name=name;
}
public String toString()
{
return"The Name of the Person:"+this.name+","+"The age of the person
is:"+this.age;
}
}

public class OverrideToStringDemo


{
public static void main(String[] args)
{
Person p1=new Person("Praveen",24);
System.out.println(p1);
Person p2=new Person("Praveen",24);
Person p3=new Person("Sujata",23);
Person p4=new Person("Sujata",23);
System.out.println(p1.equals(p2));
System.out.println(p3.equals(p4));
}
}
Output:

The Name of the Person:Praveen,The age of the person is:24


false
false

After overriding equals( ):


 After overriding equals( ), the above program become like the below.
 After overriding equals( ) , it compares two objects based on the content of the object but
not based on the memory address.
Example 2:
package com.sdj;
class Person
{
String name;
int age;
public Person(String name,int age)
{
this.age=age;
this.name=name;
}
/* overriding equals method is based on the content of object as below. */
/* Here content specifies state of the object. */
public boolean equals(Object obj)
{
Person p=(Person) obj;.
if (this.name==p.name&&this.age==p.age)
{
return true;
}
else {
return false;
}
}
public String toString()
{
return "The Name of the Person:"+this.name+","+"The age of the person is:"+this.age;
}
}
public class OverrideToStringDemo
{
public static void main(String[] args)
{
Person p1=new Person("Praveen",24);
System.out.println(p1);
Person p2=new Person("Praveen",24);
Person p3=new Person("Sujata",23);
Person p4=new Person("Sujata",23);
System.out.println(p1.equals(p2));
System.out.println(p3.equals(p4));
}
}
Output:

The Name of the Person:Praveen,The age of the person is:24


true
true

hashCode() in Object Class


 hashCode( ) will play an important role inside the Object class.
 It will return the memory location of the current object in integer format.

Syntax of hashCode method :

public int hashCode( );


 hashCode ( ) will always try to prove two objects to be equal.
Example 1:
package com.sdj;
class Person
{
String name;
int age;
public Person(String name,int age)
{
this.age=age;
this.name=name;
}
public boolean equals(Object obj)
{
Person p=(Person) obj;
if (this.name==p.name&&this.age==p.age)
{
return true;
}
else {
return false;
}
}
public String toString()
{
return"The Name of the Person:"+this.name+","+"The age of the person
is:"+this.age;
}
}
public class OverrideToStringDemo
{
public static void main(String[] args)
{
Person p1=new Person("Praveen",24);
System.out.println(p1);
Person p2=new Person("Praveen",24);
Person p3=new Person("Sujata",23);
Person p4=new Person("Sujata",23);
System.out.println(p1.equals(p2));
System.out.println(p1.hashCode()==p2.hashCode());
System.out.println(p3.equals(p4));
System.out.println(p3.hashCode()==p4.hashCode());
}
}
Output:
The Name of the Person:Praveen,The age of the person is:24
true
false
true
false
Explanation:
 In the above program p1.equals(p2) and p3.equals(p4) will return true ,but p1.hashCode() = =
p2.hashCode() and p3.hashCode() = = p4.hashCode() will return false.
 Means that equals( ) is telling p1 and p2 objects are same ,But hashCode() is telling p1 and p2
objects are different . But it is not meaningfull because one telling 2 objects are equal but another
one telling same 2 objects not equal.
 In order to make this meaningful we need to override both equals() and hashCode( ) inside our
class based on content/state of object. Either one get overrids its not advisble.

Memory manage by hasCode()


Example 2:
package com.sdj;
class Person
{
String name;
int age;
public Person(String name,int age)
{
this.age=age;
this.name=name;
}
public boolean equals(Object obj)
{
Person p=(Person) obj;
if (this.name==p.name&&this.age==p.age)
{
return true;
}
else {
return false;
}
}
public String toString()
{
return "The Name of the Person:"+this.name+","+"The age of the person
is:"+this.age;
}
}
public class OverrideToStringDemo
{
public static void main(String[] args)
{
Person p1=new Person("Praveen",24);
System.out.println(p1);
Person p2=new Person("Praveen",24);
Person p3=new Person("Sujata",23);
Person p4=new Person("Sujata",23);
System.out.println(p1.equals(p2));
System.out.println(p1.hashCode()==p2.hashCode());
Person p5=p2;
System.out.println(p5.equals(p2));
System.out.println(p5.hashCode()==p2.hashCode());
System.out.println(p3.equals(p4));
System.out.println(p3.hashCode()==p4.hashCode());
}
}
Output:

The Name of the Person:Praveen,The age of the person is:24


true
false
true
true
true
false
Explanation:
 In the above program p1.equals(p2) returns true value and p1.hashCode( )==p2.hashCode(
) will return false value.
 One method trying to say both are equal and the another method trying to say both objects
are different.
 Because here equals( ) has overrided based on the content of the object and hashCode()
does not overrided based on content it’s works based on memory location of the object.
 So in order to prove two objects are equal then we should override the both equals( ) and
hashCode( ) based on the content only.

How to override hashCode( ):


Steps to override hashCode( ):
 We have to convert all Object values into String Type.
 Then Convert it into hashcode by calling the corresponding hashcode( ) method
 Add all hashCodes and Return it.
After overriding hashCode( ):
package com.sdj;
class Person
{
String name;
int age;
public Person(String name,int age)
{
this.age=age;
this.name=name;
}
public boolean equals(Object obj)
{
Person p=(Person) obj;
if (this.name==p.name&&this.age==p.age)
{
return true;
}
else {
return false;
}
}
public int hashCode( )
{
/*Converting age attribute in to String Type*/
String strAge=Integer.toString(this.age);
int hashCode=this.name.hashCode()+strAge.hashCode();
return hashCode;
}
public String toString( )
{
return"The Name of the Person:"+this.name+","+"The age of the person
is:"+this.age;
}
}
public class OverrideToStringDemo
{
public staticvoid main(String[] args)
{
Person p1=new Person("Praveen",24);
System.out.println(p1);
Person p2=new Person("Praveen",24);
Person p3=new Person("Sujata",23);
Person p4=new Person("Sujata",23);
System.out.println(p1.equals(p2));
System.out.println(p1.hashCode()==p2.hashCode());
Person p5=p2;
System.out.println(p5.equals(p2));
System.out.println(p5.hashCode()==p2.hashCode());
System.out.println(p3.equals(p4));
System.out.println(p3.hashCode()==p4.hashCode());
}
}

Output:

The Name of the Person: Ravi.p,


The age of the person is: 24
true
true
true
true
true
true
Explanation:

Memory manage by hasCode()


toString( ),equals( ) and hashCode( ) in String class:
 equals( ) and hashCode( ) has already overrided in String class based on the content of the
object but not based on the memory address.
The following program describes very clearly:
package com.sdj;
public class StringOverrideDemo
{
public static void main(String[ ] args)
{
String s1=new String("Praveen");
String s2=new String("Praveen");
System.out.println(s1.equals(s2));
System.out.println(s1.hashCode()==s2.());
System.out.println(s1);
}
}
Output:

Output:
true
true
Praveen
Explanation:
 In the above program s1.equals(s2) and s1.hashCode( )==s2.hashCode( ) will return true
value even though we does not override equals( ) and hashCode( ) inside our class.
 Means inside String class equals( ) and hashCode( ) has already overrided based on the
content.
 Along with the equals( ) and hashCode( ), toString( ) also overrided in String class.
 Even though we pass derived object as input parameter to System.Out.println(derived
Object) we don’t get the memory address in hexadecimal format because toString( ) has
overrided in String classes.
 clone() with shallow and deep copy
clone()
 Clone( ) is used to create duplicate object to current object with same state of the current
Object .
 Clone( ) method is one of the important methods available under Object class.
 Clone( ) will give deap copy of duplicate Objects, incase of current Object it contains only
primitive values.
 Clone( ) will give Shallow copy of duplicate Objects, incase of current Object it contains any
derived type of attribute.
Deap Copy:
 Deap copy is 100% disjoint between the current object and duplicate object .
 If we change the state of object it won’t effect to the duplicate object.
Shallow Copy:
 Shallow copy is not disjoint means if we change the state of the duplicate object it will effect
to the original object.
 If we change the state of object it won’t effect to the duplicate object.

Syntax of clone method :

protected Object clone( ) throws CloneNotSupportedException


 hashCode ( ) will always try to prove two objects to be equal.
 If we want to use clone( ) we should take care of one checkedtype Exception - i.e.
CloneNotSupportedException.
 By using clone( ) we are performing unsecured operation, by default JVM will not allow to
perform any unsecured operations.
 In order to make this unsecured operation, then we should implements the clonable interface.
 Cloneable interface is a marker interface, it won’t give any features to our class it is mainly
used for the JVM purpose only in order to blame the JVM for performing unsecured
operation.
 Marker interface is an empty interface and not every empty interface is a marker interface.
 Marker interface is only for JVM purpose not for the development purpose.

In order to perform clone operation that class must implements cloneable interface. This is
a marker interface for blaming JVM in order to perform unsecured operation.
Example 1:
package com.sdj;
import java.io.IOException;
class Person implements Cloneable
{
int age;
/* clone( ) access level is protected in object class incase of */
/* inheritance it is specific to the subclass and */
/* we can’t access outside of the class. */
public Person getDuplicate()throws CloneNotSupportedException
{
Person dup=(Person) this.clone();
/*here we are doing downcasting from object type to Person type*/
return dup;
}
}
public class CloneDemo
{
public static void main(String[] args) throws CloneNotSupportedException
{
Person p=new Person();
p.age=25;
Person p1=p.getDuplicate();
System.out.println(p1.age);
p1.age=34;
System.out.println(p.age);
System.out.println(p1.age);
}
}
Output:

25 25 34

Explanation:
In the above program getDuplicate( ) is defined in the Person class.Inside this method we are
downcasting object type into person type means clone( ) will return object type.
 In the above program p is a original object and p1 is a duplicate object. Here p object
contains only primitive value means the duplicated object is Deap Copy
 Even though we modify the p1(duplicate) object value it won’t effect to the p(original)
object.
Shallow Copy
 Shallow copy is not 100% disjoint. If there are derived attributes inside the original
objects then only shallow copy gets created.
Example 2:
package com.sdj;
class Address implements Cloneable
{
int StreetNo;
int pin;
}
class Person implements Cloneable
{
int age;
double height;
Address adr;
Person(int age,double height,Address adr )
{
this.age=age;
this.height=height;
this.adr=adr;
}
/* clone( ) access level is protected in object class incase of inheritance */
/* it is specific to the subclass and we can’t access out side of the class.*/
public Person getClone() throws CloneNotSupportedException
{
return (Person)this.clone();
}
}
public class ShallowCopy
{
public static void main(String[] args)throws CloneNotSupportedException
{
Address adr =new Address();
adr.pin=517126;
adr.StreetNo=3;
Person p1=new Person(24,5.8,adr);
Person p2=p1.getClone();
System.out.println(p2.age);
System.out.println(p1.age);
p2.adr.StreetNo=7;
System.out.println(p1.adr.StreetNo);
p2.adr.pin=517123;
System.out.println(p1.adr.pin);
p1.adr.pin=517666;
System.out.println(p2.adr.pin);
}
}
Output:

24 24 7 517123 517666
Explanation:
In the above program getDuplicate( ) is defined in the Person class.Inside this method we are
downcasting object type into person type means clone( ) will return object type.
 In the above program Address is derived type attribute inside the Person class.
 If cloneable object contains any derived type attribute then that class also must implements
cloneable interface i.e. Address implements Cloneable.
 So derived type attribute class and cloneable type class must implements cloneable
interface I.e. Address implements Cloneable and Person implements cloneable
 If we change the state of the p1 object it will automatically effect to the p2 object. I,e. p1
StreetNo, pin are changed by the p2 object.
 However clone( ) with shallow copy is not advisable.
 According to Object class we can get deep copy in case of all primitive types and we can
get ShallowCopy in case of Object contains any derived type
 If we want to get the Deep copy eventhough object contains any derived type then we
should override clone( ) inside our class.

Memory manage for CloneNotSupportException


Overriding clone( ):
In order to override clone( ) our class must implements cloneable interface if our class contains
any derived type then that class also must implements.

cloneable interface.

Example 3:
package com.sdj;
class Address implements Cloneable
{
int StreetNo;
int pin;
}
class Person implements Cloneable
{
int age; double height;
Address adr;
Person(int age,double height,Address adr )
{
this.age=age;
this.height=height;
this.adr=adr;
}
/*overriding clone( )*/
public Object clone() throws CloneNotSupportedException
{
Address add=new Address();
add.StreetNo=this.adr.StreetNo;
add.pin=this.adr.pin;
Person p3=new Person(this.age,this.height,add);
return p3;
}
}
public class ShallowCopy
{
public static void main(String[] args)throws CloneNotSupportedException
{
Address adr =new Address();
adr.pin=517126; adr.StreetNo=3;
Person p1=new Person(25,5.8,adr);
Person p2=(Person)p1.clone();
System.out.println(p2.adr.pin);
p2.adr.pin=517123;
System.out.println(p1.adr.pin);
System.out.println(p2.adr.pin);
p2.adr.StreetNo=7;
System.out.println(p1.adr.StreetNo);
System.out.println(p2.adr.StreetNo);
p1.adr.StreetNo=6;
System.out.println(p1.adr.StreetNo);
P1.adr.pin=517333;
System.out.println(p1.adr.pin);
}
}
Output:

517126 517126 517123 3 7 6 517333

Explanation:
 After overriding clone( ) p1 object changes will not effect to the p2 object because two
objects have two derived objects created. one belongs to p1 object and another one
belongs to p2 object.

 In the above program p1 object pin,streetNo are not modified by the p2 object.

Memory manage when we use Overriding clone().


Java Virtual Method
When a Super class reference holds a subclass method, calling the same method using the super
class reference will automatically call the subclass method. Thus, the Super class method
actually gets hidden until we use the keyword ―Super‖. This means, using the keyword ―Super‖
only will lead to calling the Super class method. Therefore, in a way the Super class method gets
hidden. Hence, in an object oriented java programming, instead of the reference, we are calling
the method in accordance to its object. The methods which are implementing this concept are the
java virtual methods.
The prerequisites of a virtual function are:
 Inheritance
 Polymorphism
Example:
class Coach
{
//virtual method
void per()
{
System.out.println("Coach Class");
}
}
public class Sportscoach extends Coach
{
void per() { System.out.println("Sportscoach Class"); }
public static void main (String args[])
{
Coach obj = new Sportscoach();
obj.per();
}
}
Output
Sportscoach Class
A virtual function essentially holds these two concepts and this is why the private and static
methods are not virtual methods.
Things to Remember About Virtual Functions
1. A virtual function in java, is just a function of any class which is defined again in the
derived class. For a function to be virtual, you do not need any explicit declaration for the
same.
2. The base class pointer (also called reference) can be used to refer to the object of the
derived class.
3. During runtime, the base class pointer will be used to call derived class functions.
Need of Virtual Functions
1. Runtime Polymorphism
2. Invoke redefined function of the derived class through base class pointer at the runtime.
Thus, we can conclude that virtual functions are one of the simplest concepts of java language
provided they are understood and implemented according to the best of our use.

Interfaces 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.

What is an Interface?

An interface is just like Java Class, but it only has static constants and abstract method. Java uses
Interface to implement multiple inheritance. A Java class can implement multiple Java
Interfaces. All methods in an interface are implicitly public and abstract.

Syntax for Declaring Interface

interface
{
//methods
}

Why use Java interface?

There are mainly three reasons to use interface. They are given below.

o It is used to achieve abstraction.


o By interface, we can support the functionality of multiple inheritance.
o 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.
}

The relationship between classes and interfaces

As shown in the figure given below, a class extends another class, an interface extends another
interface, but a class implements an interface.

Why is an Interface required?

To understand the concept of Java Interface better, let see an example. The class "Media Player"
has two subclasses: CD player and DVD player. Each having its unique implementation method
to play music.
Another class "Combo drive" is inheriting both CD and DVD (see image below). Which play
method should it inherit? This may cause serious design issues. And hence, Java does not allow
multiple inheritance.

Real time another example for Interfaces

Suppose you have a requirement where class "dog" inheriting class "animal" and "Pet". But you
cannot extend two classes in Java. So what would you do? The solution is Interface.

The rulebook for interface says,

 An interface is 100% abstract class and has only abstract methods.


 Class can implement any number of interfaces.

Class Dog can extend to class "Animal" and implement interface as "Pet".
Java Interface Example:

Step 1) Copy following code into an editor.

interface Pet
{
public void test();
}
class Dog implements Pet
{
public void test()
{
System.out.println("Interface Method Implemented");
}
public static void main(String args[])
{
Pet p = new Dog();
p.test();
}
}

Step 2) Save , Compile & Run the code. Observe the Output.

Output: Interface Method Implemented

Must know facts about Interface

 A Java class can implement multiple Java Interfaces. It is necessary that the class must
implement all the methods declared in the interfaces.
 Class should override all the abstract methods declared in the interface
 The interface allows sending a message to an object without concerning which classes it
belongs.
 Class needs to provide functionality for the methods declared in the interface.
 All methods in an interface are implicitly public and abstract
 An interface cannot be instantiated
 An interface reference can point to objects of its implementing classes
 An interface can extend from one or many interfaces. Class can extend only one class but
implement any number of interfaces
 An interface cannot implement another Interface. It has to extend another interface if
needed.
 An interface which is declared inside another interface is referred as nested interface
 At the time of declaration, interface variable must be initialized. Otherwise, the compiler
will throw an error.
 The class cannot implement two interfaces in java that have methods with same name but
different return type.

More – Interface Example:


interface printable
{
void print();
}
class A6 implements printable
{
public void print(){System.out.println("Galgotias - MCA");}

public static void main(String args[])


{
A6 obj = new A6();
obj.print();
}
}

Output: Galgotias – MCA

Java Interface Example: Drawable

In this example, the Drawable interface has only one method. Its implementation is provided by
Rectangle and Circle classes. In a real scenario, an interface is defined by someone else, but its
implementation is provided by different implementation providers. Moreover, it is used by
someone else. The implementation part is hidden by the user who uses the interface.

//Interface declaration: by first user


interface Drawable
{
void draw();
}
//Implementation: by second user
class Rectangle implements Drawable
{
public void draw(){System.out.println("drawing rectangle");}
}
class Circle implements Drawable
{
public void draw(){System.out.println("drawing circle");}
}
//Using interface: by third user

class TestInterface1
{
public static void main(String args[])
{
Drawable d=new Circle();//In real scenario, object is provided by method
e.g. getDrawable()
d.draw();
}
}

Output: drawing circle

Java Interface Example: Bank

java interface which provides the implementation of Bank interface.


interface Bank
{
float rateOfInterest();
}
class SBI implements Bank
{
public float rateOfInterest(){return 9.15f;}
}
class PNB implements Bank
{
public float rateOfInterest(){return 9.7f;}
}
class TestInterface2
{
public static void main(String[] args)
{
Bank b=new SBI();
System.out.println("ROI: "+b.rateOfInterest());
}
}

Output: ROI: 9.15

Multiple inheritance in Java by interface

If a class implements multiple interfaces, or an interface extends multiple interfaces, it is known


as multiple inheritance.

interface Printable
{
void print();
}
interface Showable
{
void show();
}
class A7 implements Printable,Showable
{
public void print(){System.out.println("Hello");}
public void show(){System.out.println("MCA");}
public static void main(String args[])
{
A7 obj = new A7();
obj.print();
obj.show();
}
}

Output: Hello
MCA

Multiple inheritance is not supported through class in java, but it is possible by an


interface, why?

As we have explained in the inheritance, multiple inheritance is not supported in the case of class
because of ambiguity. However, it is supported in case of an interface because there is no
ambiguity. It is because its implementation is provided by the implementation class. For
example:

interface Printable
{
void print();
}
interface Showable
{
void print();
}
class TestInterface3 implements Printable, Showable
{
public void print(){System.out.println("Hello");}
public static void main(String args[])
{
TestInterface3 obj = new TestInterface3();
obj.print();
}
}
Output: Hello

Interface Inheritance

A class implements an interface, but one interface extends another interface.

interface Printable
{
void print();
}
interface Showable extends Printable
{
void show();
}
class TestInterface4 implements Showable
{
public void print(){System.out.println("Hello");}
public void show(){System.out.println("MCA");}
public static void main(String args[])
{
TestInterface4 obj = new TestInterface4();
obj.print();
obj.show();
}
}
Output: Hello

MCA

Java 8 Default Method in Interface

Since Java 8, we can have method body in interface. But we need to make it default method.

interface Drawable
{
void draw();
default void msg(){System.out.println("default method");}
}
class Rectangle implements Drawable
{
public void draw(){System.out.println("drawing rectangle");}
}
class TestInterfaceDefault
{
public static void main(String args[])
{
Drawable d=new Rectangle();
d.draw();
d.msg();
}
}
Output: drawing rectangle
default method

Java 8 Static Method in Interface

Since Java 8, we can have static method in interface.

interface Drawable
{
void draw();
static int cube(int x){return x*x*x;}
}
class Rectangle implements Drawable
{
public void draw(){System.out.println("drawing rectangle");}
}

class TestInterfaceStatic
{
public static void main(String args[])
{
Drawable d=new Rectangle();
d.draw();
System.out.println(Drawable.cube(3));
}
}

Output: drawing rectangle


27

Difference between abstract class and interface

Abstract class and interface both are used to achieve abstraction where we can declare the
abstract methods. Abstract class and interface both can't be instantiated.

Abstract class Interface

1) Abstract class can have abstract and Interface can have only abstract methods.
non-abstract methods. Since Java 8, it can have default and static
methods also.

2) Abstract class doesn't support multiple Interface supports multiple inheritance.


inheritance.
3) Abstract class can have final, non-final, Interface has only static and final variables.
static and non-static variables.

4) Abstract class can provide the Interface can't provide the implementation
implementation of interface. of abstract class.

5) The abstract keyword is used to declare The interface keyword is used to declare
abstract class. interface.

6) An abstract class can extend another An interface can extend another Java
Java class and implement multiple Java interface only.
interfaces.

7) An abstract class can be extended using An interface can be implemented using


keyword "extends". keyword "implements".

8) A Java abstract class can have class Members of a Java interface are public by
members like private, protected, etc. default.

9)Example: Example:
public abstract class Shape{ public interface Drawable{
public abstract void draw(); void draw();
} }

Simply, abstract class achieves partial abstraction (0 to 100%) whereas interface achieves fully
abstraction (100%).

Simple Example where we are using interface and abstract class both.
//Creating interface that has 4 methods
interface A
{
void a();//bydefault, public and abstract
void b();
void c();
void d();
}
//Creating abstract class that provides the implementation of one method of A interface
abstract class B implements A
{
public void c(){System.out.println("I am C");}
}
//Creating subclass of abstract class, now we need to provide the implementation of rest o
f the methods
class M extends B
{
public void a(){System.out.println("I am a");}
public void b(){System.out.println("I am b");}
public void d(){System.out.println("I am d");}
}
//Creating a test class that calls the methods of A interface
class Test5
{
public static void main(String args[])
{
A a=new M();
a.a();
a.b();
a.c();
a.d();
}
}

Output:
I am a
I am b
I am c
I am d

Java Nested Interface


An interface i.e. declared within another interface or class is known as nested interface. The
nested interfaces are used to group related interfaces so that they can be easy to maintain. The
nested interface must be referred by the outer interface or class. It can't be accessed directly.

 Nested interface must be public if it is declared inside the interface but it can have any
access modifier if declared within the class.
 Nested interfaces are declared static implicitely.

Syntax of nested interface which is declared within the interface

interface interface_name
{
...
interface nested_interface_name{
...
}
}

Example:
interface Showable
{
void show();
interface Message
{
void msg();
}
}
class TestNestedInterface1 implements Showable.Message
{
public void msg(){System.out.println("Hello MCA, This is nested interface
within Inteface");}
public static void main(String args[])
{
Showable.Message message=new TestNestedInterface1();//upcasting her
e
message.msg();
}
}

Output: Hello MCA, This is nested interface within Interface

Syntax of nested interface which is declared within the class


class class_name
{
...
interface nested_interface_name
{
...
}
}

Example:
class A
{
interface Message
{
void msg();
}
}

class TestNestedInterface2 implements A.Message


{
public void msg()
{
System.out.println("Hello MCA – This is nested interface within class");
}
public static void main(String args[])
{
A.Message message=new TestNestedInterface2(); //upcasting here
message.msg();
}
}
Output: Hello MCA – This is nested interface within Class

PACKAGES
What is Package in Java?
A Package is a collection of related classes. It helps organize your classes into a folder structure
and make it easy to locate and use them. More importantly, it helps improve re-usability.
Each package in Java has its unique name and organizes its classes and interfaces into a separate
namespace, or name group.
Although interfaces and classes with the same name cannot appear in the same package, they can
appear in different packages. This is possible by assigning a separate namespace to each
package.

Syntax:-
package nameOfPackage;

The following video takes you through the steps of creating a package.
Let's study package with an example. We define a class and object and later compile this it in our
package p1. After compilation, we execute the code as a java package.

Step 1) Consider the following code,


Here,
1. To put a class into a package, at the first line of code define package p1
2. Create a class c1
3. Defining a method m1 which prints a line.
4. Defining the main method
5. Creating an object of class c1
6. Calling method m1

Step 2) In next step, save this file as demo.java

Step 3) In this step, we compile the file.

The compilation is completed. A class file c1 is created. However, no package is created? Next
step has the solution
Step 4) Now we have to create a package, use the command

javac –d . demo.java

This command forces the compiler to create a package.

The "." operator represents the current working directory.

Step 5) When you execute the code, it creates a package p1. When you open the java package p1
inside you will see the c1.class file.

Step 6) Compile the same file using the following code

javac –d .. demo.java

Here ".." indicates the parent directory. In our case file will be saved in parent directory which is
C Drive

File saved in parent directory when above code is executed.


Step 7) Now let's say you want to create a sub package p2 within our existing java package p1.
Then we will modify our code as

package p1.p2

Step 8) Compile the file

As seen in below screenshot, it creates a sub-package p2 having class c1 inside the package.

Step 9) To execute the code mention the fully qualified name of the class i.e. the package name
followed by the sub-package name followed by the class name -
java p1.p2.c1
This is how the package is executed and gives the output as "m1 of c1" from the code file.

Importing packages
To create an object of a class (bundled in a package), in your code, you have to use its fully
qualified name.

Example:
java.awt.event.actionListner object = new java.awt.event.actionListner();
But, it could become tedious to type the long dot-separated package path name for every class
you want to use. Instead, it is recommended you use the import statement.

Syntax
import packageName;
Once imported, you can use the class without mentioning its fully qualified name.
import java.awt.event.*; // * signifies all classes in this package are imported
import javax.swing.JFrame // here only the JFrame class is imported
//Usage
JFrame f = new JFrame; // without fully qualified name.

Example: To import package

Step 1) Copy the code into an editor.


package p3;
import p1.*; //imports classes only in package p1 and NOT in the sub-package p2
class c3{
public void m3(){
System.out.println("Method m3 of Class c3");
}
public static void main(String args[]){
c1 obj1 = new c1();
obj1.m1();
}
}

Step 2) Save the file as Demo2.java. Compile the file using the command javac –d .

Demo2.java

Step 3) Execute the code using the command java p3.c3

Packages - points to note:


 To avoid naming conflicts packages are given names of the domain name of the company
in reverse Ex: com.guru99. com.microsoft, com.infosys etc.
 When a package name is not specified, a class is in the default package (the current
working directory) and the package itself is given no name. Hence you were able to
execute assignments earlier.
 While creating a package, care should be taken that the statement for creating package
must be written before any other import statements

// not allowed
import package p1.*;
package p3;

//correct syntax

package p3;
import package p1.*;

the java.lang package is imported by default for any class that you create in Java.
The Java API is very extensive, contains classes which can perform almost all programming
tasks right from Data Structure Manipulation to Networking. More often than not, you will be
using API files in your code.

-o0o-

You might also like