Using final with Inheritance in Java (original) (raw)
Last Updated : 13 Jun, 2026
The final keyword in Java is used to restrict inheritance and method overriding. It can be applied to classes, methods, and variables to enforce specific behavior. When used with inheritance, final helps maintain consistency and prevents unwanted modifications in derived classes.
- Inherited final methods cannot be overridden.
- Ensures consistent behavior across subclasses.
- Can be declared in a base class or any intermediate subclass. Java `
// base class abstract class Shape { private double width;
private double height;
// Shape class parameterized constructor
public Shape(double width, double height)
{
this.width = width;
this.height = height;
}
// getWidth method is declared as final
// so any class extending
// Shape can't override it
public final double getWidth()
{
return width;
}
// getHeight method is declared as final
// so any class extending Shape
// can not override it
public final double getHeight()
{
return height;
}
// method getArea() declared abstract because
// it upon its subclasses to provide
// complete implementation
abstract double getArea();}
// derived class one class Rectangle extends Shape { // Rectangle class parameterized constructor public Rectangle(double width, double height) { // calling Shape class constructor super(width, height); }
// getArea method is overridden and declared
// as final so any class extending
// Rectangle can't override it
@Override
final double getArea()
{
return this.getHeight() * this.getWidth();
}}
//derived class two class Square extends Shape { // Square class parameterized constructor public Square(double side) { // calling Shape class constructor super(side, side); }
// getArea method is overridden and declared as
// final so any class extending
// Square can't override it
@Override
final double getArea()
{
return this.getHeight() * this.getWidth();
}}
// Driver class public class Test { public static void main(String[] args) { // creating Rectangle object Shape s1 = new Rectangle(10, 20);
// creating Square object
Shape s2 = new Square(10);
// getting width and height of s1
System.out.println("width of s1 : "+ s1.getWidth());
System.out.println("height of s1 : "+ s1.getHeight());
// getting width and height of s2
System.out.println("width of s2 : "+ s2.getWidth());
System.out.println("height of s2 : "+ s2.getHeight());
//getting area of s1
System.out.println("area of s1 : "+ s1.getArea());
//getting area of s2
System.out.println("area of s2 : "+ s2.getArea());
}}
`
Output
width of s1 : 10.0 height of s1 : 20.0 width of s2 : 10.0 height of s2 : 10.0 area of s1 : 200.0 area of s2 : 100.0
Syntax
class Parent {
final void display() {
// code
}
}class Child extends Parent {
// display() cannot be overridden
}
Using final to Prevent Inheritance
A class declared as final cannot be inherited. This is useful when you want to create a complete and secure class whose behavior should not be modified through inheritance.
- No class can extend a final class.
- Commonly used for immutable classes.
- Provides better control over class design.
**Syntax:
final class A {
// methods and fields
}
// Compilation Error
class B extends A {
}
Java `
final class Vehicle {
void display() {
System.out.println("This is a Vehicle class.");
}}
public class Test { public static void main(String[] args) { Vehicle v = new Vehicle(); v.display(); } }
`
Output
This is a Vehicle class.
**Explanation: The Vehicle class is declared as final, so no other class can extend it. The program creates an object of Vehicle and calls its display() method successfully.
**Note :
- Declaring a class as final implicitly declares all of its methods as final, too.
- 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. For more on abstract classes, refer abstract classes in java
Using final to Prevent Overriding
Declaring a method as final prevents subclasses from overriding it. This ensures that the method's implementation remains unchanged in all derived classes.
- A final method is inherited but cannot be overridden.
- Guarantees the same implementation in every subclass.
- Useful for methods containing critical logic.
**Syntax:
class A {
final void show() {
System.out.println("Final Method");
}
}
class B extends A {
// show() cannot be overridden
}
Java `
final class Vehicle {
void display() {
System.out.println("This is a Vehicle class.");
}}
public class Test { public static void main(String[] args) { Vehicle v = new Vehicle(); v.display(); } }
`
Output
This is a Vehicle class.
**Explanation: The sound() method in the Animal class is declared as final, so the Dog class inherits it but cannot override it. The program calls the inherited sound() method and the display() method of Dog.