Inheritance, Polymorphism, and Abstraction

Object-Oriented Programming (OOP) in Salesforce Apex

Salesforce Apex is a powerful, object-oriented programming language that supports the core principles of Object-Oriented Programming (OOP). The three main OOP concepts that you can utilize in Apex are Inheritance, Polymorphism, and Abstraction. These concepts help you write modular, reusable, and maintainable code.

1. Inheritance in Salesforce Apex

Inheritance allows a new class (child class) to inherit properties and behaviors (fields and methods) from an existing class (parent class). This enables you to create a hierarchy of classes that share common functionality, reducing code duplication.

Example of Inheritance in Apex:

Let’s consider a scenario where you have a system that manages different types of accounts in a bank, such as a SavingsAccount and a CheckingAccount. Both account types share some common attributes like account number and balance, but they also have unique behaviors.

Parent Class:

public class BankAccount {
    public String accountNumber;
    public Decimal balance;
    
    public BankAccount(String accNumber, Decimal initialBalance) {
        this.accountNumber = accNumber;
        this.balance = initialBalance;
    }
    
    public void deposit(Decimal amount) {
        balance += amount;
        System.debug('Deposited: ' + amount);
    }
    
    public void withdraw(Decimal amount) {
        if (balance >= amount) {
            balance -= amount;
            System.debug('Withdrawn: ' + amount);
        } else {
            System.debug('Insufficient balance');
        }
    }
    
    public void displayBalance() {
        System.debug('Account Balance: ' + balance);
    }
}

Child Class:

public class SavingsAccount extends BankAccount {
    public Decimal interestRate;
    
    public SavingsAccount(String accNumber, Decimal initialBalance, Decimal interestRate) {
        super(accNumber, initialBalance);
        this.interestRate = interestRate;
    }
    
    public void applyInterest() {
        Decimal interest = balance * interestRate / 100;
        deposit(interest);
        System.debug('Interest Applied: ' + interest);
    }
}

Usage Example:

SavingsAccount mySavings = new SavingsAccount('SA12345', 1000, 5);
mySavings.deposit(200);        // Inherited method
mySavings.applyInterest();     // Method from child class
mySavings.displayBalance();    // Inherited method

Explanation:

  • BankAccount is the parent class with properties like accountNumber and balance, and methods for basic operations like deposit, withdraw, and displayBalance.
  • SavingsAccount is the child class that inherits from BankAccount. It adds a new property interestRate and a method applyInterest, which calculates and adds interest to the balance.

Key Points:

  • The child class (SavingsAccount) has access to all public and protected members of the parent class (BankAccount).
  • The super() keyword is used to call the parent class constructor from the child class.

2. Polymorphism in Salesforce Apex

Polymorphism allows objects of different classes to be treated as objects of a common superclass. It is often implemented through method overriding, where a child class provides a specific implementation of a method that is already defined in its parent class.

Example of Polymorphism in Apex:

Let’s extend the previous example by adding a CheckingAccount class.

Child Class:

public class CheckingAccount extends BankAccount {
    public Decimal overdraftLimit;
    
    public CheckingAccount(String accNumber, Decimal initialBalance, Decimal overdraftLimit) {
        super(accNumber, initialBalance);
        this.overdraftLimit = overdraftLimit;
    }
    
    // Overriding the withdraw method to allow overdrafts
    public override void withdraw(Decimal amount) {
        if (balance + overdraftLimit >= amount) {
            balance -= amount;
            System.debug('Withdrawn: ' + amount);
        } else {
            System.debug('Overdraft limit exceeded');
        }
    }
}

Polymorphism Example:

BankAccount myAccount;

// Polymorphic behavior: Treating different objects as BankAccount
myAccount = new SavingsAccount('SA12345', 1000, 5);
myAccount.withdraw(200); // Calls the withdraw method from BankAccount class

myAccount = new CheckingAccount('CA12345', 500, 200);
myAccount.withdraw(600); // Calls the overridden withdraw method in CheckingAccount class

Explanation:

  • CheckingAccount overrides the withdraw method from BankAccount to allow withdrawals even if the balance is below the withdrawal amount, as long as it doesn’t exceed the overdraft limit.
  • Polymorphism allows you to use a single variable (myAccount) of the type BankAccount to refer to objects of either SavingsAccount or CheckingAccount.
  • The method that gets executed is determined by the actual object type at runtime (i.e., whether myAccount is a SavingsAccount or a CheckingAccount).

Key Points:

  • Method Overriding: The child class (CheckingAccount) can provide a specific implementation of a method (withdraw) that is already defined in the parent class (BankAccount).
  • Runtime Polymorphism: The actual method that gets called depends on the object type at runtime, not on the reference type.

3. Abstraction in Salesforce Apex

Abstraction is the concept of hiding the complex implementation details of a class and exposing only the essential features. This is often achieved through the use of abstract classes and interfaces.

Example of Abstraction in Apex:

Let’s define an abstract class for different types of bank accounts.

Abstract Class:

public abstract class AbstractBankAccount {
    public String accountNumber;
    public Decimal balance;
    
    public AbstractBankAccount(String accNumber, Decimal initialBalance) {
        this.accountNumber = accNumber;
        this.balance = initialBalance;
    }
    
    // Abstract method, to be implemented by child classes
    public abstract void withdraw(Decimal amount);
    
    public void deposit(Decimal amount) {
        balance += amount;
        System.debug('Deposited: ' + amount);
    }
    
    public void displayBalance() {
        System.debug('Account Balance: ' + balance);
    }
}

Concrete Child Class:

public class FixedDepositAccount extends AbstractBankAccount {
    public Integer lockInPeriod; // In months
    
    public FixedDepositAccount(String accNumber, Decimal initialBalance, Integer lockInPeriod) {
        super(accNumber, initialBalance);
        this.lockInPeriod = lockInPeriod;
    }
    
    // Implementation of the abstract method
    public override void withdraw(Decimal amount) {
        System.debug('Withdrawals are not allowed from Fixed Deposit Account until maturity.');
    }
}

Usage Example:

FixedDepositAccount myFD = new FixedDepositAccount('FD12345', 10000, 12);
myFD.deposit(2000);
myFD.withdraw(500);  // Calls the implemented withdraw method in FixedDepositAccount
myFD.displayBalance();

Explanation:

  • AbstractBankAccount is an abstract class that cannot be instantiated directly. It contains an abstract method withdraw, which must be implemented by any non-abstract subclass.
  • FixedDepositAccount is a concrete class that extends AbstractBankAccount and provides a specific implementation of the withdraw method, which restricts withdrawals until maturity.

Key Points:

  • Abstract Classes: Abstract classes serve as a blueprint for other classes. They can contain both abstract methods (which must be implemented by subclasses) and concrete methods (with full implementations).
  • Interfaces: Salesforce Apex also supports interfaces, which can be used to define a contract that classes must adhere to. Interfaces only contain method signatures without any implementation.

Tutorials Deck

TutorialsDeck is striving to provide the best learning material on technical and non-technical subjects.

Languages

Web Technologies

Database

Trending Technologies

© 2024. All rights reserved.

Contact Us @ tutorialsdeck06@gmail.com