JAVA Notes Unit 2 Print
JAVA Notes Unit 2 Print
Inheritance
Inheritance is an important pillar of OOP (Object-Oriented Programming). It is
the mechanism in Java by which one class is allowed to inherit the features (fields
and methods) of another class.
In Java, Inheritance means creating new classes based on existing ones. A class
that inherits from another class can reuse the methods and fields of that class. In
addition, you can add new fields and methods to your current class as well.
The class which inherits the properties of other is known as subclass (derived
class, child class) and the class whose properties are inherited is known as superclass
(base class, parent class).
Need of Inheritance
class Super
{
.....
.....
}
class Sub extends Super
{
.....
.....
}
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.
When one class inherits multiple classes, it is known as multiple inheritance. For
Example: there are three classes A, B, and C. The C class inherits A and B classes. If
A and B classes have the same method and we call it from child class object, there will
be ambiguity to call the method of A or B class.
1. Single Inheritance:
In single inheritance, a sub-class is derived from only one super class. It
inherits the properties and behavior of a single-parent class. Sometimes, it is also
known as simple inheritance. In the below figure, ‘A’ is a parent class and ‘B’ is a
child class. The class ‘B’ inherits all the properties of the class ‘A’.
// Subclass: Car
class Car extends Vehicle
{
int numberOfDoors;
2. Multilevel Inheritance
3. Hierarchical Inheritance
In Hierarchical Inheritance, one class serves as a superclass (base class) for
more than one subclass. In the below image, class A serves as a base class for the
derived classes B, C, and D.
// Subclass: Car
class Car extends Vehicle
{
int numberOfDoors;
// Subclass: Truck
class Truck extends Vehicle
{
int loadCapacity;
public Truck(String brand, int speed, int loadCapacity)
{
super(brand, speed);
this.loadCapacity = loadCapacity;
}
public void displayTruckInfo()
{
displayInfo();
System.out.println("Load Capacity: " + loadCapacity + " tons");
}
}
//Main Class
public class Hierarchical
{
public static void main(String[] args)
{
Car c = new Car("Honda", 160, 4);
Truck t = new Truck("Volvo", 120, 15);
c.displayCarInfo();
t.displayTruckInfo();
}
}
In Multiple inheritances, one class can have more than one superclass and
inherit features from all parent classes. Please note that Java
does not support multiple inheritances with classes. In Java, we can achieve multiple
inheritances only through Interfaces. In the image below, Class C is derived from
interfaces A and B.
// Interface 2: Fuel
interface Fuel
{
void setFuelType(String fuelType);
void displayFuelType();
}
@Override
public void setSpeed(int speed)
{
this.speed = speed;
}
@Override
public void displaySpeed()
{
System.out.println("Speed: " + speed + " km/h");
}
@Override
public void setFuelType(String fuelType)
{
this.fuelType = fuelType;
}
@Override
public void displayFuelType()
{
System.out.println("Fuel Type: " + fuelType);
}
v.displayBrand();
v.displaySpeed();
v.displayFuelType();
}
}
5. Hybrid Inheritance
It is a mix of two or more of the above types of inheritance. Since Java doesn’t
support multiple inheritances with classes, hybrid inheritance involving multiple
inheritance is also not possible with classes. In Java, we can achieve hybrid
inheritance only through Interfaces if we want to involve multiple inheritance to
implement Hybrid inheritance.
// Interface 2: Engine
interface Engine
{
void startEngine();
void stopEngine();
}
// Superclass: Vehicle
class Vehicle
{
String brand;
@Override
public void setSpeed(int speed)
{
this.speed = speed;
}
@Override
public void displaySpeed()
{
System.out.println("Speed: " + speed + " km/h");
}
@Override
public void startEngine()
{
System.out.println("Engine started.");
}
@Override
public void stopEngine()
{
System.out.println("Engine stopped.");
}
}
//Main class
public class Hybrid
{
public static void main(String[] args)
{
Car c = new Car("BMW");
c.displayBrand();
c.setSpeed(220);
c.displaySpeed();
c.startEngine();
c.stopEngine();
}
}
1. Specialization
2. Specification
3. Construction
4. Extension or Generalization
5. Limitation
6. Combination
1. Specialization
It is the most ideal form of inheritance. The subclass is a special case of the
parent class. It holds the principle of substitutability.
2. Specification
This is another commonly used form of inheritance. In this form of inheritance,
the parent class just specifies which methods should be available to the child class
but doesn't implement them. The java provides concepts like abstract and interfaces
to support this form of inheritance. It holds the principle of substitutability.
3. Construction
This is another form of inheritance where the child class may change the
behavior defined by the parent class (overriding). It does not hold the principle of
substitutability.
4. Extension or Generalization
This is another form of inheritance where the child class may add its new
properties. It holds the principle of substitutability.
5. Limitation
This is another form of inheritance where the subclass restricts the inherited
behavior. It does not hold the principle of substitutability.
6. Combination
This is another form of inheritance where the subclass inherits properties from
multiple parent classes. Java does not support multiple inheritance type.
1. public Members
Superclass: public members of the superclass are accessible from any class,
including subclasses, regardless of the package.
Subclass: A subclass can access public members of its superclass without any
restriction.
2. private Members
3. protected Members
Superclass: protected members of the superclass are accessible within the same
package and in subclasses (even if they are in different packages).
Subclass: A subclass can access protected members of its superclass, whether
the subclass is in the same package or in a different package.
Superclass: Members with default access (no modifier) are accessible only
within the same package.
Subclass: If the subclass is in the same package, it can access these members. If
the subclass is in a different package, it cannot access these members.
// Subclass of Vehicle
class Car extends Vehicle
{
public Car(String brand, int year, String model, String color)
{
super(brand, year, model, color);
}
// Subclass can access protected member and method
public void displayCarInfo()
{
System.out.println("Brand: " + brand);
System.out.println("Model (from subclass): " + model); // access protected member
displayModel(); // Can call protected method
}
}
// Main class
public class Access
{
public static void main(String[] args)
{
Vehicle v = new Vehicle("Toyota", 2020, "Corolla", "Red");
// Public member can be accessed directly
System.out.println("Brand: " + v.brand);
// Cannot access private member directly, so using the public getter method
System.out.println("Year: " + v.getYear());
// Cannot access private method directly
//v.displayPrivateInfo(); // This would cause a compile-time error
// Accessing default/package-private member within the same package
System.out.println("Color: " + v.color);
// Subclass can access protected members and methods
Car c = new Car("Honda", 2021, "Civic", "Blue");
c.displayCarInfo();
}
}
super keyword
1. super in Variables: Used to access a variables from the superclass, especially if the
subclass has a field with the same name.
2. super in Methods: Used to call a method from the superclass, especially when the
method is overridden in the subclass.
3. Super() in Constructors: Used to invoke a constructor of the superclass. If the
superclass doesn't have a no-argument constructor, you need to call one of its
constructors explicitly using super().
// Main class
public class SuperKey
{
public static void main(String[] args)
{
Car c = new Car("Toyota", 2020, 4);
c.displayCarInfo();
}
}
Restrictions on super:
Polymorphism
The term "polymorphism" means "many forms". In object-oriented
programming, polymorphism is useful when you want to create multiple forms with
the same name of a single entity.
1. Method Overloading
2. Method Overriding
// Child Class
class Child extends Parent
{
// Method Overriding
public void m1(int a)
{
System.out.println("Child Method m1 with parameter: " + a);
}
}
// Main Method
class Poly
{
public static void main(String args[])
{
Parent p = new Parent();
p.m1();
p.m1(5);
Child c = new Child();
c.m1(4);
}
}
// Subclass of Vehicle
class Car extends Vehicle
{
public Car(String brand)
{
super(brand);
}
// Overriding the hornSound method in the Car class
public void hornSound()
{
System.out.println(super.brand + " horn sound: Honk Honk!");
}
}
//Main class
public class Override
{
public static void main(String[] args)
{
Vehicle v = new Vehicle("Toyota");
v.hornSound();
Car c = new Car("Honda");
c.hornSound();
}
}
abstract classes
Abstraction in Java
Abstraction is a process of showing the essential features and hiding their
implementation details to the user.
1. Abstract Class
An abstract class in Java acts as a partially implemented class that itself cannot be
instantiated. It exists only for subclassing purposes, and provides a template for its
subcategories to follow. Abstract classes can have implementations with abstract
methods. Abstract methods are declared to have no body, leaving their implementation
to subclasses.
Points to Remember
// Subclass: Car
class Car extends Vehicle
{
public Car(String brand, int speed)
{
super(brand, speed);
}
// Implementing the abstract method startEngine
void startEngine()
{
System.out.println("Car engine started.");
}
}
// Subclass: Truck
class Truck extends Vehicle
{
int loadCapacity; // in tons
public Truck(String brand, int speed, int loadCapacity)
{
super(brand, speed);
this.loadCapacity = loadCapacity;
}
// Implementing the abstract method startEngine
void startEngine()
{
System.out.println("Truck engine started.");
}
// Method specific to Truck class
public void displayLoadCapacity()
{
System.out.println("Load Capacity: " + loadCapacity + " tons");
}
}
//Main class
public class Abstraction
{
public static void main(String[] args)
{
// Creating objects of Car and Truck
Car c = new Car("Toyota", 180);
Truck t = new Truck("Volvo", 100, 10);
// Calling methods
c.startEngine();
c.displayInfo();
t.startEngine();
t.displayInfo();
t.displayLoadCapacity();
}
}
final keyword
1. Final Variables (Constants): When you declare a variable as final, its value
cannot be changed once it is assigned. Essentially, the variable becomes a
constant.
4. Final Parameters: You can also use the final keyword on method parameters,
which makes the parameters immutable within the method.
// Constructor
Vehicle(String brand, int year)
{
this.brand = brand;
this.year = year;
}
// Method with final parameter
public void setVehicleType(final String vehicleType)
{
// Uncommenting the following line would cause a compilation error
// vehicleType = "Truck"; // Error: cannot assign a value to final variable
System.out.println("Vehicle type is: " + vehicleType);
}
// Final method: Cannot be overridden by subclasses
final void displayInfo()
{
System.out.println("Brand: " + brand + ", Year: " + year);
}
}
// Uncommenting the following line will cause a compile-time error because Vehicle
is final
// class Car extends Vehicle
// {
// }
// Main class
public class FinalKey
{
public static void main(String[] args)
{
Vehicle v = new Vehicle("Toyota", 2020);
// Passing a String parameter to the setVehicleType method
v.setVehicleType("Car");
// The final variable brand cannot be reassigned
// v.brand = "Honda"; // This would cause a compile-time error
v.displayInfo(); // Calling the final method
}
}
Syntax of Interface
interface InterfaceName
{
void method1(); // Abstract method (no body)
// Default method with implementation
default void method2()
{
System.out.println("This is a default method in the interface.");
}
// Static method with implementation
static void method3()
{
System.out.println("This is a static method in the interface.");
}
}
As shown in the figure given below, a class extends another class, an interface
extends another interface, but a class implements an interface.
System.out.println("\nTruck Actions:");
t.start();
t.accelerate();
t.honk();
t.stop();
}
}
Abstract class can have final, non- Interface has only static and final
6.
final, static and non-static variables. variables.
Example: Example:
public abstract class Shape public interface Drawable
11. { {
public abstract void draw(); void draw();
} }
Packages
Creating and accessing a package
In Java, packages are used to group related classes and interfaces together. This
helps in organizing code in a logical manner and avoiding name conflicts. A package
also controls access to classes and members, helping with encapsulation.
Types of Packages:
1. Built-in Packages: These are provided by the Java API (e.g., java.util, java.io,
java.lang). They come pre-installed with the Java Development Kit (JDK).
2. User-defined Packages: These are packages that you define for your own
classes and interfaces.
Importance of Packages?
1. Organization: Packages allow you to logically group related classes and interfaces,
making it easier to maintain and manage code.
2. Name Conflict Avoidance: By placing classes in different packages, you can avoid
name conflicts between classes with the same name.
3. Access Control: Packages provide a way to control access to classes, methods, and
variables using access modifiers like private, protected, and public.
4. Reusability: Packages allow code to be reused across different projects by creating
modular and organized libraries.
At the top of a Java source file, you can declare the package it belongs to using the
package keyword:
package package_name;
Ex:
package com.mahindra.utility;
public class Vehicle
{
// class implementation
}
1. Built-In Packages
In Java, built-in packages are predefined and included in the Java Standard
Library (Java API). These packages provide a wide range of functionality that can be
used directly in your programs without having to write the code yourself.
The Java standard library contains packages that allow you to work with data
structures, file handling, networking, utilities, and more.
Here are some of the most commonly used built-in packages in Java:
1. java.lang Package
Description: This is one of the most fundamental packages in Java. It is
automatically imported in every Java program, so you don’t need to explicitly
import it.
Classes and Interfaces:
o String: Represents strings of characters.
o Math: Provides mathematical functions like sqrt(), pow(), etc.
o Object: The root class of the Java class hierarchy.
o System: Provides system-related utility methods (e.g.,
System.out.println() ).
o Thread: Represents a thread of execution.
o Exception, RuntimeException: Represents exceptions in Java.
2. java.util Package
Description: Provides classes and interfaces for data structures, date and time,
and utility classes.
Classes and Interfaces:
3. java.io Package
Description: Contains classes and interfaces for input and output (I/O)
operations like reading from or writing to files, and working with data streams.
Classes and Interfaces:
4. java.net Package
5. java.sql Package
Description: Provides classes and interfaces for working with databases using
JDBC (Java Database Connectivity).
Classes and Interfaces:
o Connection: Represents a connection to a database.
o Statement: Used to execute SQL queries.
o ResultSet: Represents the result set of a query.
o DriverManager: Manages database drivers.
6. java.awt Package
import java.lang.*;
import java.util.ArrayList;
import java.io.*;
import java.io.IOException;
import java.awt.*;
By grouping related classes into packages, you can avoid naming conflicts and
improve code readability and maintainability.
1. Create a Package: To define a user-defined package, use the package keyword at the
top of your Java source file.
2. Compile the Class: After defining the package, compile the Java file from the
directory above the package directory.
3. Import the Package: If you want to use classes from a package in another class, use
the import keyword.
Let's go through an example where we create a vehicle package, define classes related
to vehicles in that package, and then access those classes from another package.
Steps:
package vehicle;
// Constructor
public Vehicle(String brand, int year)
{
this.brand = brand;
this.year = year;
}
package vehicle;
Now, in a different package, we create a Main class to demonstrate how to use the
Vehicle and Car classes.
//Main.java
import vehicle.Vehicle;
import vehicle.Car;
1. vehicle Package:
o The Vehicle class has basic properties such as brand and year, along with
methods to get and set those properties. It also has a displayInfo() method to
print the vehicle's information.
o The Car class extends Vehicle and adds a doors property, representing the
number of doors in the car. It overrides the displayInfo() method to include the
number of doors in the output.
2. Main Class:
o The Main class imports the Vehicle and Car classes from the vehicle
package using the import statement.
o It then creates instances of both the Vehicle and Car classes and calls their
displayInfo() methods.
Directory Structure:
To compile and run the above code, your directory structure should look like this:
bin/
│
├── vehicle/
│ ├── Vehicle.java
│ └── Car.java
│
└── Main.java
Understanding CLASSPATH
In Java, the CLASSPATH is an environment variable that tells the Java Virtual
Machine (JVM) and Java compiler where to look for compiled Java class files and
other resources like libraries (JAR files) when executing a program.
When you run a Java program, the JVM needs to find the classes that are part of
your program. By default, the JVM looks for classes in the current directory. However,
if your classes are located in different directories or JAR files, you need to specify
these locations via the CLASSPATH environment variable.
What it can contain:
A jar file is created using jar tool. The general command looks somewhat like this:
jar – file : name of jar file on which you want to use jar tool.
file1, file2, file3 : files which you want to add inside a jar file. manifest-file is
the name of file which contains manifest of that jar file, giving manifest-file as
an argument is entirely optional.
c : Creates a new or empty archive and adds files to it. If any of the specified
file name are directories, then the jar program processes them recursively.
C : Temporarily changes the directory.
e : Creates an entry point in the manifest.
f : Specifies the JAR file name as the second command-line argument. If this
parameter is missing, jar will write the result to standard output (when creating
a JAR file)or read it from standard input(when extracting or tabulating a JAR
file).
i : Creates an index file.
m : Adds a manifest file to the JAR file. A manifest is a description of the
archive contents and origin. Every archive has a default manifest, but you can
supply your own if you want to authenticate the contents of the archive.
M : Does not create a manifest file for the entries.
t : Displays the table of contents.
u : Updates an existing JAR file.
v : Generates verbose output.
x : Extract files. If you supply one or more file names, only those files are
extracted Otherwise, all files are extracted.
1. Directory Structure:
To compile and run the above code, your directory structure should look like this:
bin/
│
├── vehicle/
│ ├── Vehicle.java
│ └── Car.java
│
└── Main.java
2. Compile the Java Files
To compile the Java files, navigate to the src directory and compile the .java files:
This will compile the Java files and place the resulting .class files in the bin directory,
following the package structure.
To specify the entry point of your application (the class with the main method), you
need to create a manifest file with the Main-Class attribute. The manifest file will tell
the JVM which class to run when you execute the JAR file.
/MyProject
/META-INF
MANIFEST.MF
Main-Class: The fully qualified class name of the class that contains the main
method to execute. In this case, Main.
You can now create the JAR file using the jar command. Use the -m option to
specify your custom MANIFEST.MF file and the -C option to include your compiled
.class files from the bin directory.
After running the command, the myapp.jar file will be created, containing the classes
and manifest.
Once the JAR file is created, you can run it using the java -jar command. The java -jar
command will automatically use the Main-Class attribute from the manifest file to
determine which class to execute.
Temporarily or
Permanently
To set the CLASSPATH temporarily for a session (only for the current command
prompt), you can use the following:
set CLASSPATH=C:\path\to\classes;C:\path\to\jarfile.jar
C:\path\to\your\bin;C:\path\to\libs\library1.jar;C:\path\to\libs\library2.jar
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
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.
Built-in exceptions are part of the Java standard library and provide a
standardized way to handle common exceptional scenarios.
1. Checked Exceptions
2. Unchecked Exceptions
The unchecked exceptions are just opposite to the checked exceptions. The
compiler will not check these exceptions at compile time. In simple words, if a
program throws an unchecked exception, and even if we didn’t handle or declare it,
the program would not give a compilation error. Examples of Unchecked Exception
are listed below:
package vehicle;
else
{
isRunning = true;
System.out.println(brand + " engine started.");
}
}
// Method to stop the vehicle engine
public void stopEngine()
{
if (!isRunning)
{
throw new IllegalStateException("The vehicle engine is not running.");
}
isRunning = false;
System.out.println(brand + " engine stopped.");
}
// Method to refuel the vehicle
public void refuel(int amount)
{
if (amount <= 0)
{
throw new IllegalArgumentException("Refuel amount must be positive.");
}
fuelLevel += amount;
if (fuelLevel > 100)
{
fuelLevel = 100; // Fuel level cannot exceed 100%
}
System.out.println(brand + " refueled. Current fuel level: " + fuelLevel + "%");
}
// Method to drive the vehicle
public void drive()
{
if (!isRunning)
{
throw new IllegalStateException("The vehicle is not running. Start the engine first.");
}
System.out.println(brand + " is driving.");
}
}
//Main.java
import vehicle.Vehicle;
public class Main
{
public static void main(String[] args)
{
try
{
// Create a new vehicle with a valid fuel level
Vehicle v1 = new Vehicle("Toyota", 50);
Output:
1. try block
A try block consists of all the doubtful statements that can throw exceptions.
A try block cannot be executed on itself; it requires at least one catch block
or finally block.
If an exception occurs, the control flows from the try-to-catch block.
When an exception occurs in a try block, the appropriate exception object is
redirected to the catch block. This catch block handles the exception
according to its statements and continues the execution.
Syntax
try
{
//Doubtful Statements.
}
2. catch block
The catch block handles the exception raised in the try block.
The catch block or blocks follow every try block.
The catch block catches the thrown exception as its parameter and executes
the statements inside it.
The declared exception must be the parent class exception, the generated
exception type in the exception class hierarchy, or a user-defined
exception.
Syntax
try
{
//Doubtful Statements.
}
catch(Exception e)
{
// code to handle exceptions
}
We can use multiple catch statements for different kinds of exceptions that can
occur from a single block of code in the try block.
Syntax
try
{
// code to check exceptions
}
catch (exception1)
{
// code to handle the exception
}
catch (exception2)
{
// code to handle the exception
}
3. finally block
The finally block in Java always executes even if there are no exceptions. This
is an optional block. It is used to execute important statements such as closing
statements, releasing resources, and releasing memory. There could be one final block
for every try block. This finally block executes after the try...catch block.
Syntax
try
{
//code
}
catch (ExceptionType1 e1)
{
// catch block
}
finally
{
// finally block always executes
}
4. throw Keyword
Syntax
5. throws keyword
The throws keyword is used in the method signature to indicate that a method
in Java can throw particular exceptions. This notifies the method that it must manage
or propagate these exceptions to the caller.
Syntax
Here's an example of how each of these can be used in the context of a Vehicle class.
class Vehicle
{
private boolean isRunning = false;
private int fuelLevel = 10; // Fuel level out of 100
// Method to start the vehicle
public void start()
{
System.out.println("Vehicle is starting...");
isRunning = true;
}
// Method to stop the vehicle
public void stop()
{
if (!isRunning)
{
// Throw a custom unchecked exception if trying to stop an already stopped vehicle
throw new VehicleAlreadyStoppedException("Vehicle is already stopped.");
}
System.out.println("Vehicle is stopping...");
isRunning = false;
}
// Method to accelerate the vehicle
public void accelerate(int speed)
{
try
{
if (speed < 0)
{
throw new IllegalArgumentException("Speed cannot be negative.");
}
System.out.println("Accelerating to " + speed + " km/h...");
}
catch (IllegalArgumentException e)
{
System.out.println("Error while accelerating: " + e.getMessage());
}
finally
{
System.out.println("Acceleration attempt completed.");
}
}
catch (VehicleAlreadyStoppedException e)
{
System.out.println("Caught exception in stop method: " + e.getMessage());
}
Syntax
Syntax
Statements
You just need to extend the predefined RuntimeException class to create your own
Exception.
class Vehicle
{
private boolean isRunning = true;
private int fuelLevel = 10; // Fuel level out of 100
catch (OutOfFuelException e)
{
System.out.println("Caught exception in drive method: " + e.getMessage());
}
}
}