Java Notes IA-2
Java Notes IA-2
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 we can create new classes that are built upon existing
classes. When we inherit methods from an existing class, we can reuse methods and fields of the
parent class. However, we can add new methods and fields in your current class also.
What is Inheritance?
Inheritance in Java enables a class to inherit properties and actions from another class, called a
superclass or parent class. A class derived from a superclass is called a subclass or child group.
Through inheritance, a subclass can access members of its superclass (fields and methods),
enforce reuse rules, and encourage hierarchy.
Inheritance represents the IS-A relationship which is also known as a parent-child relationship.
The extends keyword indicates that we 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 that is inherited is called a parent or superclass, and the new
class is called child or subclass.
1. class Employee{
2. float salary=40000;
3. }
4. class Programmer extends Employee{
5. int bonus=10000;
6. public static void main(String args[]){
7. Programmer p=new Programmer();
8. System.out.println("Programmer salary is:"+p.salary);
9. System.out.println("Bonus of Programmer is:"+p.bonus);
10. }
11. }
Test it Now
Programmer salary is:40000.0
Bonus of programmer is:10000
In the above example, Programmer object can access the field of own class as well as of
Employee class i.e. code reusability.
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.
Note: Multiple inheritance is not supported in Java through class.
When one class inherits multiple classes, it is known as multiple inheritance. For Example:
File: TestInheritance.java
class Animal{
void eat(){System.out.println("eating...");}
}
class Dog extends Animal{
void bark(){System.out.println("barking...");}
}
class TestInheritance{
public static void main(String args[]){
Dog d=new Dog();
d.bark();
d.eat();
}}
Output:
barking...
eating...
When there is a chain of inheritance, it is known as multilevel inheritance. As you can see in the
example given below, BabyDog class inherits the Dog class which again inherits the Animal
class, so there is a multilevel inheritance.
File: TestInheritance2.java
class Animal{
void eat(){System.out.println("eating...");}
}
class Dog extends Animal{
void bark(){System.out.println("barking...");}
}
class BabyDog extends Dog{
void weep(){System.out.println("weeping...");}
}
class TestInheritance2{
public static void main(String args[]){
BabyDog d=new BabyDog();
d.weep();
d.bark();
d.eat();
}}
Output:
weeping...
barking...
eating...
Interface in Java
An interface in Java is a blueprint of a class. It has static constants and abstract methods.
The interface in Java is a mechanism to achieve abstraction. There can be only abstract methods
in the Java interface, not method body. It is used to achieve abstraction and multiple inheritance
in Java.
In other words, you can say that interfaces can have abstract methods and variables. It cannot
have a method body.
There are mainly three reasons to use interface. They are given below.
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>{
interface Animal {
void eat();
void sleep();
}
In this example, the Animal interface declares two method signatures: eat() and sleep(). Any
class implementing the Animal interface must provide concrete implementations for these
methods.
Since Java 8, interface can have default and static methods which is discussed later.
The Java compiler adds public and abstract keywords before the interface method. Moreover, it
adds public, static and final keywords before data members.
In other words, Interface fields are public, static and final by default, and the methods are public
and abstract.
As shown in the figure given below, a class extends another class, an interface extends another
interface, but a class implements an interface.
In this example, the Printable interface has only one method, and its implementation is provided
in the A6 class.
File Name: InterfaceExample.java
interface printable{
void print();
}
class InterfaceExample implements printable{
public void print(){System.out.println("Hello");}
public static void main(String args[]){
InterfaceExample obj = new InterfaceExample();
obj.print();
}
}
Output:
Hello
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.
File: TestInterface1.java
Output:
drawing circle
Let's see another example of java interface which provides the implementation of Bank interface.
File: TestInterface2.java
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());
}}
Test it Now
Output:
ROI: 9.15
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("Welcome");}
Output:
Hello
Welcome
Java Package
Package in java can be categorized in two form, built-in package and user-defined package.
There are many built-in packages such as java, lang, awt, javax, swing, net, io, util, sql etc.
Here, we will have the detailed learning of creating and using user-defined packages.
1) Java package is used to categorize the classes and interfaces so that they can be easily
maintained.
//save as Simple.java
package mypack;
public class Simple{
public static void main(String args[]){
System.out.println("Welcome to package");
}
}
If you are not using any IDE, you need to follow the syntax given below:
1. javac -d . Simple.java
The -d switch specifies the destination where to put the generated class file. You can use any
directory name like /home (in case of Linux), d:/abc (in case of windows) etc. If you want to
keep the package within the same directory, you can use . (dot).
You need to use fully qualified name e.g. mypack.Simple etc to run the class.
Output:Welcome to package
The -d is a switch that tells the compiler where to put the class file i.e. it represents destination. The . represents
the current folder.
There are three ways to access the package from outside the package.
import package.*;
import package.classname;
1) Using packagename.*
If you use package.* then all the classes and interfaces of this package will be accessible but not
subpackages.
The import keyword is used to make the classes and interface of another package accessible to
the current package.
//save by A.java
package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
import pack.*;
class B{
public static void main(String args[]){
A obj = new A();
obj.msg();
}
}
Output:Hello
2) Using packagename.classname
If you import package.classname then only declared class of this package will be accessible.
//save by A.java
package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
import pack.A;
class B{
public static void main(String args[]){
A obj = new A();
obj.msg();
}
}
Output:Hello
If you use fully qualified name then only declared class of this package will be accessible. Now
there is no need to import. But you need to use fully qualified name every time when you are
accessing the class or interface.
It is generally used when two packages have same class name e.g. java.util and java.sql packages
contain Date class.
//save by A.java
package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
class B{
public static void main(String args[]){
pack.A obj = new pack.A();//using fully qualified name
obj.msg();
}
}
Output:Hello
If you import a package, all the classes and interface of that package will be imported excluding
the classes and interfaces of the subpackages. Hence, you need to import the subpackage as well.
Note: Sequence of the program must be package then import then class.
Subpackage in java
Package inside the package is called the subpackage. It should be created to categorize the
package further.
Let's take an example, Sun Microsystem has definded a package named java that contains many
classes like System, String, Reader, Writer, Socket etc. These classes represent a particular group
e.g. Reader and Writer classes are for Input/Output operation, Socket and ServerSocket classes
are for networking etc and so on. So, Sun has subcategorized the java package into subpackages
such as lang, net, io etc. and put the Input/Output related classes in io package, Server and
ServerSocket classes in net packages and so on.
Example of Subpackage
package com.javatpoint.core;
class Simple{
public static void main(String args[]){
System.out.println("Hello subpackage");
}
}
To Compile: javac -d . Simple.java
Output:Hello subpackage
There is a scenario, I want to put the class file of A.java source file in classes folder of c: drive.
For example:
//save as Simple.java
package mypack;
public class Simple{
public static void main(String args[]){
System.out.println("Welcome to package");
}
}
To Compile:
To Run:
To run this program from e:\source directory, you need to set classpath of the directory where the class file
resides.
e:\sources> set classpath=c:\classes;.;
The -classpath switch can be used with javac and java tool.
To run this program from e:\source directory, you can use -classpath switch of java that tells
where to look for class file. For example:
Output:Welcome to package
Exception Handling in Java
The Exception Handling in Java is one of the powerful mechanism to handle the runtime
errors so that the normal flow of the application can be maintained.
In this section, we will learn about Java exceptions, it's types, and the difference between
checked and unchecked exceptions.
In Java, an exception is an event that occurs during the execution of a program that disrupts the
normal flow of instructions. These exceptions can occur for various reasons, such as invalid user
input, file not found, or division by zero. When an exception occurs, it is typically represented by
an object of a subclass of the java.lang.Exception class.
The core advantage of exception handling is to maintain the normal flow of the application.
An exception normally disrupts the normal flow of the application; that is why we need to handle
exceptions. Let's consider a scenario:
statement 1;
statement 2;
statement 3;
statement 4;
statement 5;//exception occurs
statement 6;
statement 7;
statement 8;
statement 9;
statement 10;
Suppose there are 10 statements in a Java program and an exception occurs at statement 5; the
rest of the code will not be executed, i.e., statements 6 to 10 will not be executed. However,
when we perform exception handling, the rest of the statements will be executed. That is why we
use exception handling in Java.
The java.lang.Throwable class is the root class of Java Exception hierarchy inherited by two
subclasses: Exception and Error. The hierarchy of Java Exception classes is given below:
Types of Java Exceptions
In Java, exceptions are categorized into two main types: checked exceptions and unchecked
exceptions. Additionally, there is a third category known as errors. Let's delve into each of these
types:
1. Checked Exception
2. Unchecked Exception
3. Error
1. Checked Exceptions
Checked exceptions are the exceptions that are checked at compile-time. This means that the
compiler verifies that the code handles these exceptions either by catching them or declaring
them in the method signature using the throws keyword. Examples of checked exceptions
include:
ParseException: Indicates a problem while parsing a string into another data type, such as
parsing a date.
Unchecked exceptions, also known as runtime exceptions, are not checked at compile-time.
These exceptions usually occur due to programming errors, such as logic errors or incorrect
assumptions in the code. They do not need to be declared in the method signature using the
throws keyword, making it optional to handle them. Examples of unchecked exceptions include:
3. Errors
Errors represent exceptional conditions that are not expected to be caught under normal
circumstances. They are typically caused by issues outside the control of the application, such as
system failures or resource exhaustion. Errors are not meant to be caught or handled by
application code. Examples of errors include:
OutOfMemoryError: It occurs when the Java Virtual Machine (JVM) cannot allocate enough
memory for the application.
NoClassDefFoundError: It indicates that the JVM cannot find the definition of a class that was
available at compile-time.
Understanding the different types of exceptions in Java is crucial for writing robust and reliable
code. By handling exceptions appropriately, you can improve the resilience of your applications
and provide better user experiences.hierarchy of exception handling
Here are the key differences between checked exceptions, unchecked exceptions (runtime
exceptions), and errors in Java:
1. Checked Exceptions:
Compile-time Check: Checked exceptions are checked at compile-time by the Java compiler.
This means that the compiler ensures that these exceptions are either caught or declared in the
method signature using the throws keyword.
Forced Handling: Checked exceptions enforce explicit handling, either by catching them or
declaring them to be thrown. This helps in improving code reliability and robustness.
Recovery Possible: Checked exceptions typically represent recoverable conditions, such as file
not found or database connection failure, where the application may take corrective action.
Optional Handling: Handling of unchecked exceptions is optional. While it's good practice to
handle them for robustness, it's not mandatory.
3. Errors:
Not Meant for Handling: Errors represent exceptional conditions that are typically beyond the
control of the application and are not meant to be caught or handled by application code.
Critical Conditions: Errors usually indicate critical conditions, such as JVM failures or system
resource exhaustion, where the application cannot recover.
Java provides five keywords that are used to handle the exception. The following table describes
each.
Keyword Description
One of the primary mechanisms for handling exceptions in Java is the try-catch block. The try
block contains the code that may throw an exception, and the catch block is used to handle the
exception if it occurs. Here's a basic example:
try {
// Code that may throw an exception
} catch (ExceptionType e) {
// Exception handling code
}
Handling Multiple Exceptions
You can handle multiple types of exceptions by providing multiple catch blocks, each catching a
different type of exception. This allows you to tailor your exception handling logic based on the
specific type of exception thrown. Here's an example:
try {
// Code that may throw an exception
} catch (IOException e) {
// Handle IOException
} catch (NumberFormatException e) {
// Handle NumberFormatException
} catch (Exception e) {
// Handle any other exceptions
}
In addition to try and catch, Java also provides a finally block, which allows you to execute
cleanup code, such as closing resources, regardless of whether an exception occurs or not. The
finally block is typically used to release resources that were acquired in the try block. Here's an
example:
try {
// Code that may throw an exception
} catch (Exception e) {
// Exception handling code
} finally {
// Cleanup code
}
JavaExceptionExample.java
Output:
There are given some scenarios where unchecked exceptions may occur. They are as follows:
1. int a=50/0;//ArithmeticException
Output:
We have a main() method where we attempt to perform division by zero that is not allowed in
arithmetic.
Inside the try block, we perform the division operation dividend / divisor, where divisor is
assigned the value of 0.
When the division by zero occurs, an ArithmeticException is thrown. We catch this exception
using a catch block specifically for ArithmeticException.
In the catch block, we handle the exception by printing an error message, indicating that division
by zero is not allowed. Additional error handling logic can be added here if needed.
String s=null;
System.out.println(s.length());//NullPointerException
Output:
Inside the try block, we attempt to call the length() method on the str reference, which is null.
String s="abc";
int i=Integer.parseInt(s);//NumberFormatException
Output:
We have a main() method where we initialize a String variable str with non-numeric characters.
Inside the try block, we attempt to parse the string str to an integer using the Integer.parseInt()
method.
Since the string contains non-numeric characters, the parsing operation throws a
NumberFormatException.
In the catch block, we handle the exception by printing an error message indicating that the
string could not be parsed as an integer. Additional error handling logic can be added here if
needed.
When an array exceeds to it's size, the ArrayIndexOutOfBoundsException occurs. there may be
other reasons to occur ArrayIndexOutOfBoundsException. Consider the following statements.
Output:
Inside the try block, we attempt to access an element at index 10, which is out of bounds for the
array numbers.
In the catch block, we handle the exception by printing an error message indicating that the index
is out of bounds. Additional error handling logic can be added here if needed.
A try block can be followed by one or more catch blocks. Each catch block must contain a
different exception handler. So, if you have to perform different tasks at the occurrence of
different exceptions, use java multi-catch block.
Points to remember
o At a time only one exception occurs and at a time only one catch block is executed.
o All catch blocks must be ordered from most specific to most general, i.e. catch for
ArithmeticException must come before catch for Exception.
Flowchart of Multi-catch Block
Example 1
MultipleCatchBlock1.java
try{
int a[]=new int[5];
a[5]=30/0;
}
catch(ArithmeticException e)
{
System.out.println("Arithmetic Exception occurs");
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("ArrayIndexOutOfBounds Exception occurs");
}
catch(Exception e)
{
System.out.println("Parent Exception occurs");
}
System.out.println("rest of the code");
}
}
Test it Now
Output: