Object-Oriented Programming in Apex – III

Object-Oriented Programming (OOP) is a popular programming model used to design software by organizing it around objects. These objects can represent real-world entities like customers, products, or even abstract concepts like transactions or data sets. In Apex, Salesforce’s programming language, OOP is a key feature that allows developers to write clean, modular, and scalable code.

Let’s break down the core OOP concepts in a simple and intuitive way, ideal for those just starting their programming journey.


1. Core OOP Concepts

Inheritance

Inheritance allows a new class (called a child class) to inherit properties and behaviors (methods) from an existing class (called a parent class). This promotes code reuse and makes your code more organized.

Example:

public class Vehicle {
    public String fuelType;
    
    public void start() {
        System.debug('Vehicle started');
    }
}

public class Car extends Vehicle {
    public Integer numberOfDoors;
    
    public void honk() {
        System.debug('Car honked');
    }
}

In this example, Car inherits the fuelType and start() method from the Vehicle class but adds its own property numberOfDoors and method honk().

Key Takeaway:

  • Inheritance allows you to reuse code and extend functionality from existing classes.

Polymorphism

Polymorphism allows objects of different classes to be treated as objects of a common parent class. It’s like having a single method that can behave differently based on the object that’s calling it.

Polymorphism comes in two forms:

  1. Compile-Time Polymorphism (Method Overloading)
  2. Run-Time Polymorphism (Method Overriding)

Compile-Time Polymorphism (Method Overloading): This occurs when multiple methods share the same name but differ in parameters.

Example:

public class Calculator {
    public Integer add(Integer a, Integer b) {
        return a + b;
    }

    public Double add(Double a, Double b) {
        return a + b;
    }
}

Run-Time Polymorphism (Method Overriding): This happens when a child class overrides a method in its parent class.

Example:

public class Vehicle {
    public virtual void start() {
        System.debug('Vehicle started');
    }
}

public class Car extends Vehicle {
    public override void start() {
        System.debug('Car started');
    }
}

Key Takeaway:

  • Overloading occurs when multiple methods with the same name are distinguished by their parameters (compile-time).
  • Overriding allows a subclass to modify or extend the functionality of a method inherited from a parent class (run-time).

Encapsulation

Encapsulation is all about bundling data (variables) and methods that operate on that data within a class and restricting access to some of the object’s components.

In Apex, we achieve encapsulation using access specifiers like private, public, and protected, which control visibility.

Example:

public class BankAccount {
    private Double balance;

    public Double getBalance() {
        return balance;
    }

    public void deposit(Double amount) {
        balance += amount;
    }
}

Here, balance is private, meaning it can’t be accessed directly from outside the class. However, we provide methods (getBalance and deposit) to interact with it.

Key Takeaway:

  • Encapsulation protects data from being accessed or modified directly from outside the class, ensuring better control and security.

Abstraction

Abstraction focuses on hiding complex implementation details and showing only the necessary functionality. It allows the developer to focus on what an object does rather than how it does it.

In Apex, abstraction is achieved using interfaces, abstract classes, and virtual methods.

1. Interfaces: An interface defines methods without providing any implementation. A class implementing the interface must provide the method implementations.

Example:

public interface VehicleInterface {
    void start();
}

public class Car implements VehicleInterface {
    public void start() {
        System.debug('Car started');
    }
}

2. Abstract Classes: An abstract class can have both defined and undefined methods (methods without implementation). Subclasses must implement abstract methods.

Example:

public abstract class Vehicle {
    public abstract void start();  // Abstract method (no implementation)
    
    public void stop() {  // Regular method
        System.debug('Vehicle stopped');
    }
}

public class Car extends Vehicle {
    public override void start() {
        System.debug('Car started');
    }
}

3. Virtual Methods: A method that is declared as virtual in the base class can be overridden by derived classes.

Key Takeaway:

  • Abstraction simplifies complexity by showing only essential features and hiding unnecessary details.

2. Advanced OOP Concepts: Generalization, Specialization, and Aggregation

Generalization:

Generalization refers to creating a common base class from multiple related classes by extracting shared properties and methods. It allows you to write general methods that can work with different but related classes.

Example: Vehicle is a general class for Car and Bike.

Specialization:

Specialization is the opposite of generalization. It refers to creating specialized classes by adding new properties or methods to an existing base class.

Example: Car is a specialized class of Vehicle.

Aggregation:

Aggregation represents a “whole-part” relationship where the part can exist independently of the whole. In simple terms, an object can contain other objects, but the contained objects can live on their own.

Example:

public class Car {
    public Engine engine;  // Car "has-a" Engine

    public Car(Engine engine) {
        this.engine = engine;
    }
}

Here, Car has an Engine, but the engine can exist without the car.

Key Takeaway:

  • Generalization is used to group common behaviors.
  • Specialization is used to create specific behaviors.
  • Aggregation represents a relationship where one object contains another, but they can exist separately.

Conclusion

Mastering these OOP concepts is crucial to writing clean, efficient, and scalable code in Apex. Whether it’s reusing code through inheritance, ensuring security through encapsulation, simplifying complexity via abstraction, or handling different behaviors with polymorphism, these principles form the backbone of professional Apex development.

Start experimenting with these concepts, and you’ll quickly build your confidence in writing professional-grade Apex code!