final Keyword Usage in Inheritance:
Final Class:
- A class declared
finalcannot be subclassed. You use it to prevent inheritance.
Final Method:
- A method declared
finalcannot 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
finalcan 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
finalvariables to define constants that should remain unchanged, even in subclasses. - To create immutable objects: A combination of
finalclasses andfinalvariables 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
finalfor 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
finalcannot 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
finalmethods 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
finalfor 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
}
}
