JAVA-Notes-Unit-2_Part 1
JAVA-Notes-Unit-2_Part 1
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
}
}