UNIT 03
Inheritance and Reusability
Contents
• Inheritance – Basics, using super, creating a
multilevel hierarchy, Java polymorphism, method
overloading, method overriding, Runtime
polymorphism, dynamic binding, aggregation,
abstract classes, using final with inheritance,
wrapper classes, packages, defining a package,
package example, access protection, interfaces–
defining an interface, implementing interfaces,
applying interfaces, variables in interfaces,
extending interfaces.
Inheritance
• Inheritance is one of the cornerstones of object-
oriented programming because it allows the creation
of hierarchical classifications.
• Using inheritance, you can create a general class that
defines traits common to a set of related items.
• This class can then be inherited by other, more specific
classes, each adding those things that are unique to it.
• In the terminology of Java, a class that is inherited is
called a superclass. The class that does the inheriting is
called a subclass.
• Therefore, a subclass is a specialized version of a
superclass.
• It inherits all of the instance variables and methods
defined by the superclass and adds its own, unique
elements
• In more simpler terms 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 parent-
child relationship.
• The two major reasons why we use inheritance in
java is:
1. For Method Overriding (so runtime
polymorphism can be achieved).
2. For Code Reusability.
• There are various terminologies associated with
inheritance.
1. Class: A class is a group of objects which have
common properties. It is a template or blueprint
from which objects are created.
2. 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.
3. 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.
4. 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 basic syntax of inheritance is as follows:
class Subclass-name extends Superclass-name
{
//methods and fields
}
• The ’extends’ keyword indicates that you are
making a new class that derives from an existing
class.
• The meaning of "extends" is to increase the
functionality.
• In the terminology of Java, a class which is
inherited is called a parent or superclass, and the
new class is called child or subclass.
• Java inheritance example:
• Programmer is the subclass and Employee is the
superclass.
• The relationship between the two classes
is Programmer IS-A Employee. It means that
Programmer is a type of Employee.
class Employee{
float salary=40000;
}
class Programmer extends Employee{
int bonus=10000;
public static void main(String args[]){
Programmer p=new Programmer();
[Link]("Programmer salary is:"+[Link]);
[Link]("Bonus of Programmer is:"+[Link]);
} }
• In the above example, Programmer object can access
the field of own class as well as of Employee class i.e.
code reusability.
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.
Single Inheritance
class Animal{
void eat()
{ [Link]("eating...");}
}
class Dog extends Animal{
void bark()
{ [Link]("barking...");}
}
class TestInheritance{
public static void main(String args[]){
Dog d=new Dog();
[Link]();
[Link]();
}}
Multilevel Inheritance
class Animal{
void eat()
{ [Link]("eating...");}
}
class Dog extends Animal{
void bark()
{ [Link]("barking...");}
}
class BabyDog extends Dog{
void weep()
{[Link]("weeping...");}
}
class TestInheritance2{
public static void main(String args[]){
BabyDog d=new BabyDog();
[Link]();
[Link]();
[Link]();
}}
Hierarchical Inheritance
class Animal{
void eat(){[Link]("eating...");}
}
class Dog extends Animal{
void bark(){[Link]("barking...");}
}
class Cat extends Animal{
void meow(){[Link]("meowing...");}
}
class TestInheritance3{
public static void main(String args[]){
Cat c=new Cat();
[Link]();
[Link]();
//[Link]();
}}
Using Super Keyword
• 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 is as follows:
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.
class Animal{
String color="white";
}
class Dog extends Animal{
String color="black";
void printColor(){
[Link](color);//prints color of Dog class
[Link]([Link]);//prints color of Animal class
}
}
class TestSuper1{
public static void main(String args[]){
Dog d=new Dog();
[Link]();
• 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.
class Animal{
void eat(){[Link]("eating...");}
}
class Dog extends Animal{
void eat(){[Link]("eating bread...");}
void bark(){[Link]("barking...");}
void work(){
[Link]();
bark();
}
}
class TestSuper2{
public static void main(String args[]){
Dog d=new Dog();
[Link]();
}}
• 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.
class Animal{
Animal(){[Link]("animal is created");}
}
class Dog extends Animal{
Dog(){
super();
[Link]("dog is created");
}
}
class TestSuper3{
public static void main(String args[]){
Dog d=new Dog();
}}
• Output:
animal is created
dog is created
• super() is added in each class constructor automatically by compiler
if there is no super() or this().
Polymorphism in Java
• Polymorphism in Java is a concept by which we
can perform a single action in different ways.
Polymorphism is derived from 2 Greek words:
poly and morphs.
• The word "poly" means many and "morphs"
means forms. So polymorphism means many
forms.
• There are two types of polymorphism in Java:
compile-time polymorphism and runtime
polymorphism.
• We can perform polymorphism in java by method
overloading and method overriding.
• If you overload a static method in Java, it is the
example of compile time polymorphism.
Runtime Polymorphism
• Runtime polymorphism or Dynamic Method
Dispatch is a process in which a call to an
overridden method is resolved at runtime rather
than compile-time.
• In this process, an overridden method is called
through the reference variable of a superclass.
• The determination of the method to be called is
based on the object being referred to by the
reference variable.
• Let's first understand the upcasting before
Runtime Polymorphism.
• Upcasting: If the reference variable of Parent
class refers to the object of Child class, it is
known as upcasting.
• For example:
class A{}
class B extends A{}
A a=new B();//upcasting
• In this example, we are creating two classes Bike
and Splendor.
• Splendor class extends Bike class and overrides its
run() method.
• We are calling the run method by the reference
variable of Parent class.
• Since it refers to the subclass object and subclass
method overrides the Parent class method, the
subclass method is invoked at runtime.
• Since method invocation is determined by the
JVM not compiler, it is known as runtime
polymorphism.
class Bike{
void run(){[Link]("running");}
}
class Splendor extends Bike{
void run(){[Link]("running safely with
60km");}
public static void main(String args[]){
Bike b = new Splendor();//upcasting
[Link]();
}
}
Dynamic Binding
• Connecting a method call to the method body is
known as binding.
• There are two types of binding:
1. Static Binding: When the type of object is
determined at compile time.
2. Dynamic Binding: When the type of object is
determined at runtime.
• When type of the object is determined at run-
time, it is known as dynamic binding.
• In Dynamic binding compiler doesn’t decide
the method to be called.
• Overriding is a perfect example of dynamic
binding.
• In overriding both parent and child classes
have the same method.
class Animal{
void eat()
{ [Link]("animal is eating...");}
}
class Dog extends Animal{
void eat(){[Link]("dog is eating...");}
public static void main(String args[]){
Animal a=new Dog();
[Link]();
} }
Output:
dog is eating...
• In the above example object type cannot be
determined by the compiler, because the instance of
Dog is also an instance of Animal.
• So compiler doesn't know its type, only its base type.
Abstract Class
• Data abstraction is the process of hiding certain
details and showing only essential information to
the user.
• Another way, it shows only essential things to the
user and hides the internal details, for example,
sending SMS where you type the text and send
the message.
• You don't know the internal processing about the
message delivery.
• Abstraction lets you focus on what the object
does instead of how it does it.
• A class which is declared with the abstract
keyword is known as an abstract class in Java.
• It can have abstract and non-abstract methods
(method with the body).
• The abstract keyword is a non-access modifier,
used for classes and methods.
• Abstract class: is a restricted class that cannot be
used to create objects (to access it, it must be
inherited from another class).
• Abstract method: can only be used in an abstract
class, and it does not have a body. The body is
provided by the subclass (inherited from).
• An abstract class can have both abstract and regular
methods
abstract class Animal
{
public abstract void animalSound();
public void sleep()
{ [Link]("Zzz"); } }
• From the example above, it is not possible to
create an object of the Animal class:
Animal myObj = new Animal();
• The above statement will generate an error.
• To access the abstract class, it must be inherited
from another class.
abstract class Animal {
abstract void makeSound();
public void eat() {
[Link]("I can eat.");
}}
class Dog extends Animal {
// provide implementation of abstract method
public void makeSound() {
[Link]("Bark bark");
}}
class Main {
public static void main(String[] args) {
// create an object of Dog class
Dog d1 = new Dog();
[Link]();
[Link]();
}}
• Output:
Bark bark
I can eat.
• In the above example, we have created an
abstract class Animal.
• The class contains an abstract
method makeSound() and a non-abstract
method eat().
• We have inherited a subclass Dog from the
superclass Animal.
• Here, the subclass Dog provides the
implementation for the abstract
method makeSound().
abstract class MotorBike {
abstract void brake();
}
class SportsBike extends MotorBike {
// implementation of abstract method
public void brake() {
[Link]("SportsBike Brake");
}}
class MountainBike extends MotorBike {
// implementation of abstract method
public void brake() {
[Link]("MountainBike Brake");
}}
class Main {
public static void main(String[] args) {
MountainBike m1 = new MountainBike();
[Link]();
SportsBike s1 = new SportsBike();
[Link]();
} }
• Output:
MountainBike Brake
SportsBike Brake
• In the above example, we have created an abstract
super class MotorBike. The superclass MotorBike has
an abstract method brake().
• The brake() method cannot be implemented
inside MotorBike. It is because every bike has different
implementation of brakes. So, all the subclasses
of MotorBike would have different implementation
of brake().
• So, the implementation of brake() in MotorBike is kept
hidden.
• Here, MountainBike makes its own implementation
of brake() and SportsBike makes its own
implementation of brake().
1. We use the abstract keyword to create abstract
classes and methods.
2. An abstract method doesn't have any
implementation (method body).
3. A class containing abstract methods should also
be abstract.
4. We cannot create objects of an abstract class.
5. To implement features of an abstract class, we
inherit subclasses from it and create objects of
the subclass.
6. A subclass must override all abstract methods of
an abstract class. However, if the subclass is
declared abstract, it's not mandatory to override
abstract methods.
Wrapper Class
• The wrapper class in Java provides the
mechanism to convert primitive into object and
object into primitive.
• Wrapper classes provide a way to use primitive
data types (int, boolean, etc..) as objects.
• Each of the 8 primitive types has corresponding
wrapper classes.
• Sometimes we can use wrapper classes, for
example when working with Collection objects,
such as ArrayList, where primitive types cannot
be used (the list can only store objects)
• Primitive Types to Wrapper Objects
class Main {
public static void main(String[] args) {
// create primitive types
int a = 5;
double b = 5.65;
//converts into wrapper objects
Integer aObj = [Link](a);
Double bObj = [Link](b);
if(aObj instanceof Integer) {
[Link]("An object of Integer is created.");
}
if(bObj instanceof Double) {
[Link]("An object of Double is created.");
}}}
• Output:
An object of Integer is created.
An object of Double is created.
• In the above example, we have used
the valueOf() method to convert the primitive
types into objects.
• Here, we have used the instanceof operator to
check whether the generated objects are
of Integer or Double type or not.
• However, the Java compiler can directly convert
the primitive types into corresponding objects.
• Let us consider an example for the same.
int a = 5;
// converts into object
Integer aObj = a;
double b = 5.6;
// converts into object
Double bObj = b;
• This process is known as auto-boxing.
• Wrapper Objects into Primitive Types
class Main {
public static void main(String[] args) {
// creates objects of wrapper class
Integer aObj = [Link](23);
Double bObj = [Link](5.55);
// converts into primitive types
int a = [Link]();
double b = [Link]();
[Link]("The value of a: " + a);
[Link]("The value of b: " + b);
}
}
• output:
The value of a: 23
The value of b: 5.55
• In the above example, we have used
the intValue() and doubleValue() method to
convert the Integer and Double objects into
corresponding primitive types.
• However, the Java compiler can automatically
convert objects into corresponding primitive
types
• Let us see an example for the same.
Integer aObj = [Link](2);
// converts into int type
int a = aObj;
Double bObj = [Link](5.55);
// converts into double type
double b = bObj;
• This process is known as unboxing.
Packages
• Packages are containers for classes that are used
to keep the class name space compartmentalized.
• For example, a package allows you to create a
class named List, which you can store in your own
package without concern that it will collide with
some other class named List stored elsewhere.
• Packages are stored in a hierarchical manner and
are explicitly imported into new class definitions.
• A unique name had to be used for each class to
avoid name collisions.
• After a while, without some way to manage the
name space, you could run out of convenient,
descriptive names for individual classes.
• You also need some way to be assured that the
name you choose for a class will be reasonably
unique and not collide with class names chosen
by other programmers.
• Imagine a small group of programmers fighting
over who gets to use the name “Foobar” as a
class name. Or, imagine the entire Internet
community arguing over who first named a class
“Espresso.”
• Thankfully, Java provides a mechanism for
partitioning the class name space into more
manageable chunks. This mechanism is the
package.
• The package is both a naming and a visibility
control mechanism.
• You can define classes inside a package that are
not accessible by code outside that package.
• You can also define class members that are only
exposed to other members of the same package.
• This allows your classes to have intimate
knowledge of each other, but not expose that
knowledge to the rest of the world.
Defining a Package
• To create a package is quite easy: simply include a
package command as the first statement in a Java
source file.
• Any classes declared within that file will belong to
the specified package.
• The package statement defines a name space in
which classes are stored.
• If you omit the package statement, the class
names are put into the default package, which
has no name.
• This is why you haven’t had to worry about
packages before now.
• While the default package is fine for short,
sample programs, it is inadequate for real
applications.
• Most of the time, you will define a package for
your code.
• For example, the following statement creates a
package called MyPackage.
package MyPackage;
• Java uses file system directories to store
packages.
• For example, the .class files for any classes you
declare to be part of MyPackage must be stored
in a directory called MyPackage.
• Remember that case is significant, and the
directory name must match the package name
exactly.
• More than one file can include the same package
statement.
• The package statement simply specifies to which
package the classes defined in a file belong.
• It does not exclude other classes in other files
from being part of that same package.
• Most real-world packages are spread across many
files.
• You can create a hierarchy of packages. To do so,
simply separate each package name from the one
above it by use of a period.
• The general form of a multileveled package
statement is shown here:
package pkg1[.pkg2[.pkg3]];
• A package hierarchy must be reflected in the file
system of your Java development system.
• For example, a package declared as
package [Link];
needs to be stored in java\awt\image in a Windows
environment.
• Be sure to choose your package names carefully.
You cannot rename a package without renaming
the directory in which the classes are stored.
Package Example
• Call this file [Link] and put it in a
directory called MyPack.
• Next, compile the file. Make sure that the resulting
.class file is also in the MyPack directory.
• Then, try executing the AccountBalance class, using the
following command line:
java [Link]
• Remember, you will need to be in the directory above
MyPack when you execute this command.
• As explained, AccountBalance is now part of the
package MyPack.
• This means that it cannot be executed by itself.
• That is, you cannot use this command line:
java AccountBalance
AccountBalance must be qualified with its package name.
Access Protection/ Access Modifiers
• Java provides many levels of protection to allow
fine-grained control over the visibility of variables
and methods within classes, subclasses, and
packages.
• Classes and packages are both means of
encapsulating and containing the name space
and scope of variables and methods.
• Packages act as containers for classes and other
subordinate packages.
• Classes act as containers for data and code. The
class is Java’s smallest unit of abstraction.
Because of the interplay between classes and
packages.
• Java addresses four categories of visibility for
class members:
1. Subclasses in the same package
2. Non-subclasses in the same package •
3. Subclasses in different packages
4. Classes that are neither in the same package nor
subclasses
• The three access specifiers, private, public, and
protected, provide a variety of ways to produce
the many levels of access required by these
categories.
• In simple words Access modifiers help to restrict
the scope of a class, constructor, variable,
method, or data member.
• It provides security, accessibility, etc to the user
depending upon the access modifier used with
the element.
• There are four types of access modifiers available
in Java:
1. Default – No keyword required
2. Private
3. Protected
4. Public
Default Access Modifier
• When no access modifier is specified for a class,
method, or data member – It is said to be having
the default access modifier by default.
• The data members, classes, or methods that are
not declared using any access modifiers i.e.
having default access modifiers are
accessible only within the same package.
Private Access Modifier
• The private access modifier is specified using the
keyword private. The methods or data members
declared as private are accessible only within the
class in which they are declared.
• Any other class of the same package will not be
able to access these members.
• Top-level classes or interfaces can not be declared
as private because
– private means “only visible within the enclosing class”.
– protected means “only visible within the enclosing
class and any subclasses”
• Hence these modifiers in terms of application to
classes, apply only to nested classes and not on
top-level classes
Protected Access Modifier
• The protected access modifier is specified
using the keyword protected.
• The methods or data members declared as
protected are accessible within the same
package or subclasses in different packages.
Public Access modifier
• The public access modifier is specified using the
keyword public.
• The public access modifier has the widest
scope among all other access modifiers.
• Classes, methods, or data members that are
declared as public are accessible from
everywhere in the program.
• There is no restriction on the scope of public data
members.
Interfaces
• Using the keyword interface, you can fully
abstract a class’ interface from its
implementation. That is, using interface, you can
specify what a class must do, but not how it does
it.
• Interfaces are syntactically similar to classes, but
they lack instance variables, and their methods
are declared without any body.
• In practice, this means that you can define
interfaces that don’t make assumptions about
how they are implemented.
• Once it is defined, any number of classes can
implement an interface.
• Also, one class can implement any number of
interfaces.
• To implement an interface, a class must create
the complete set of methods defined by the
interface.
• However, each class is free to determine the
details of its own implementation.
• By providing the interface keyword, Java allows
you to fully utilize the “one interface, multiple
methods” aspect of polymorphism.
• Interfaces are designed to support dynamic
method resolution at run time.
• Normally, in order for a method to be called from
one class to another, both classes need to be
present at compile time so the Java compiler can
check to ensure that the method signatures are
compatible.
Defining an Interface
• An interface is defined much like a class.
• This is the general form of an interface:
• When no access specifier is included, then default
access results, and the interface is only available
to other members of the package in which it is
declared.
• When it is declared as public, the interface can be
used by any other code.
• In this case, the interface must be the only public
interface declared in the file, and the file must
have the same name as the interface.
• name is the name of the interface, and can be
any valid identifier.
• Notice that the methods that are declared have
no bodies..
• They end with a semicolon after the parameter
list.
• They are, essentially, abstract methods; there can
be no default implementation of any method
specified within an interface.
• Each class that includes an interface must
implement all of the methods.
• Variables can be declared inside of interface
declarations.
• They are implicitly final and static, meaning they
cannot be changed by the implementing class.
• They must also be initialized. All methods and
variables are implicitly public
• Here is an example of an interface definition. It
declares a simple interface that contains one
method called callback( ) that takes a single
integer parameter.
interface Callback
{ void callback(int param);
}
Implementing Interfaces
• Once an interface has been defined, one or more
classes can implement that interface.
• To implement an interface, include the
implements clause in a class definition, and then
create the methods defined by the interface.
• The general form of a class that includes the
implements clause looks like this:
• If a class implements more than one interface,
the interfaces are separated with a comma.
• If a class implements two interfaces that declare
the same method, then the same method will be
used by clients of either interface.
• The methods that implement an interface must
be declared public.
• Also, the type signature of the implementing
method must match exactly the type signature
specified in the interface definition
Assignment
Applying interfaces
Variables in interfaces
Extending interfaces
Note: Study theory of these topics and refer to
basic programs of the same.