Java
Java
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.
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.
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:
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...
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.
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. }
Advantages of Inheritance
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
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
}
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
When a class extends only one class, then it is called single level inheritance.
Syntax:
class A
{
//code
}
class B extends A
{
//code
}
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.
Syntax:
class A
{
//code
}
class B extends A
{
//code
}
class C extends B
{
//code
}
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.
Syntax:
class A
{
// code
}
class B extends A
{
// code
}
class C extends A
{
//code
}
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.
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.
public
The member with public modifiers can be accessed by any classes. The public methods, variables or class
have the widest scope.
default
When we do not mention any access modifier, it is treated as default. It is accessible only within same
package.
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.
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.
Output:
Private int a = 101
String s = TutorialRide
101 TutorialRide
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.
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 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.
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
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
Output:
Compile time error
MULTILEVEL HIERARCHY IN JAVA PROGRAMMING
CREATING MULTILEVEL HIERARCHY
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.
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);
}
}
Output:
Rollno = 102689
Name = RATHEESH
Total = 350
Percentage = 70
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
}
}
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 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.
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.
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.
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.
• 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 .
―this is used to refer the current object whereas the super is used to refer to the super class.
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.
@Override
public String toString() {
return ("My name is " + name
+ " and I am " + age + " years old.");
}
}
@Override
public String toString() {
return super.toString() + " My profession is " + specialty;
}
}
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.
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.
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 {
class B extends A {
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.
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.
// ...
}
// ...
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( ).
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!");
}
}
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);
}
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.
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.
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*/
}
}
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.
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.
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.
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.
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:
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.
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.
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.
interface
{
//methods
}
There are mainly three reasons to use interface. They are given below.
Syntax:
interface <interface_name>{
As shown in the figure given below, a class extends another class, an interface extends another
interface, but a class implements an interface.
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.
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.
Class Dog can extend to class "Animal" and implement interface as "Pet".
Java Interface Example:
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.
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.
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.
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();
}
}
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
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
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
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
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));
}
}
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.
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.
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.
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
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.
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();
}
}
Example:
class A
{
interface Message
{
void msg();
}
}
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.
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
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.
javac –d .. demo.java
Here ".." indicates the parent directory. In our case file will be saved in parent directory which is
C Drive
package p1.p2
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.
Step 2) Save the file as Demo2.java. Compile the file using the command javac –d .
Demo2.java
// 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-