final Keyword Usage in Inheritance:
-
Final Class:
-
A class declared
final
cannot be subclassed. You use it to prevent inheritance.
-
-
Final Method:
-
A method declared
final
cannot be overridden by subclasses. It is used when you want to ensure that a particular method’s behavior remains unchanged.
-
-
Final Variable:
-
A variable declared
final
can only be assigned once and cannot be modified after initialization. This is typically used for constants.
-
When to Use final keyword in Inheritance:
-
To prevent modification: If you don’t want the behavior of a method or class to be altered, declare it as
final
. -
For constants: Use
final
variables to define constants that should remain unchanged, even in subclasses. -
To create immutable objects: A combination of
final
classes andfinal
variables can be used to create immutable objects, where the object’s state cannot be altered once created.
1. Final Class
A class declared with the final
keyword cannot be subclassed or extended. This means no other class can inherit from it.
-
Usage: You use
final
for classes when you want to prevent any further inheritance, ensuring that the class’s behavior cannot be modified by subclasses.
// Final class that cannot be extended final class Animal { public void sound() { System.out.println("Some generic animal sound"); } } class Elephant extends Animal { // This will give a compilation error public void sound() { System.out.println("trumpet"); } } public class Test { public static void main(String[] args) { Animal animal = new Elephant(); animal.sound(); } }
Another Example:
In this case, a BankAccount
class is declared as final
so it cannot be extended by any other class. This ensures the security and integrity of the banking logic.
// Final class cannot be extended final class BankAccount { private double balance; public BankAccount(double initialBalance) { this.balance = initialBalance; } public void deposit(double amount) { balance += amount; } public void withdraw(double amount) { if (amount <= balance) { balance -= amount; } else { System.out.println("Insufficient balance."); } } public void displayBalance() { System.out.println("Account balance: " + balance); } } public class Test { public static void main(String[] args) { BankAccount account = new BankAccount(1000); account.deposit(500); account.withdraw(300); account.displayBalance(); // Output: Account balance: 1200 } }
2. Final Method
A method declared as final
cannot be overridden by any subclass. This is useful when you want to maintain the implementation of a method in a superclass, preventing any modification of its behavior in derived classes.
-
Usage: Use
final
methods when you want to prevent overriding but still want to allow inheritance.
Example
A method such as withdraw
is marked as final
to prevent subclasses from altering its behavior, which could be dangerous in the context of banking.
class BankAccount { private double balance; public BankAccount(double initialBalance) { this.balance = initialBalance; } // Final method: Cannot be overridden by subclasses public final void withdraw(double amount) { if (amount <= balance) { balance -= amount; System.out.println("Withdrawal successful. Amount: " + amount); } else { System.out.println("Insufficient balance."); } } public void deposit(double amount) { balance += amount; } public void displayBalance() { System.out.println("Account balance: " + balance); } } class SavingsAccount extends BankAccount { public SavingsAccount(double initialBalance) { super(initialBalance); } // Attempting to override the withdraw method will cause a compile-time error // public void withdraw(double amount) { // System.out.println("Overridden withdraw method in SavingsAccount"); // } } public class Test { public static void main(String[] args) { BankAccount account = new BankAccount(1000); account.withdraw(200); // Output: Withdrawal successful. Amount: 200 } }
3. Final Variable
A variable declared as final
can only be assigned once. Once a final variable is initialized, its value cannot be changed. This is useful when you want to create constants or ensure that certain variables are not modified after initialization.
-
Usage: Use
final
for constants or fields that should not be reassigned, even if they are inherited by subclasses.
Example
class BankAccount { private double balance; public final double interestRate = 0.03; // Final variable to store interest rate public BankAccount(double initialBalance) { this.balance = initialBalance; } public void applyInterest() { balance += balance * interestRate; } public void displayBalance() { System.out.println("Account balance after interest: " + balance); } } public class Test { public static void main(String[] args) { BankAccount account = new BankAccount(1000); account.applyInterest(); account.displayBalance(); // Output: Account balance after interest: 1030.0 } }