OOP and Apex Notes - Lecture 6

Object-Oriented Programming (OOP)

  • Organizes a program as interacting objects.
  • Involves defining object types, creating instances, and specifying object communication.

Key Concepts of OOP

  • Classes and Objects: Class is a blueprint; object is an instance.
  • Encapsulation: Hides internal details, exposes controlled interface.
  • Inheritance: Allows new classes to inherit from existing ones.
  • Polymorphism: Treats objects of different classes as objects of a common superclass.
  • Abstraction: Exposes essential features, hides unnecessary details.

Objects

  • Entities with unique characteristics.
  • Software development perspective: save state (information) and offer operations (behaviour).

Object Data and Behaviours

  • Data (Attributes): Represents the object's state.
  • Behaviour (Methods): Represents what the object can do.

Software Objects vs Business Objects

  • Software Objects: Implement logic and behaviour in a system.
  • Business Objects: Model real-world business concepts.
  • In enterprise systems, OOP classes implement business objects (e.g., Order in Salesforce).

Classes

  • Definitions of object characteristics (attributes) and behaviours (methods).
  • Blueprint for creating objects.
  • Objects are instances of a class.

Class Example: Customer

  • Describes attributes (CustomerID, FirstName, LastName, Email, Phone) and behaviours (placeOrder, makePayment).

Creating Objects from Classes

  • Classes are templates for objects.
  • Many instances of a class can exist at runtime, each with its own state.

Apex Class Syntax

  • Uses access modifiers, sharing modes, class name, and class body.
  • Example: private | public | global [virtual | abstract | with sharing | without sharing] class ClassName [implements InterfaceNameList] [extends ClassName] { // Class Body }

Access Modifiers and Sharing Modes

  • Private: Accessible only locally.
  • Public: Accessible within the organization and namespace.
  • Global: Accessible by all Apex code, irrespective of the organisation.
  • With Sharing: Enforces user's access and permissions.
  • Without Sharing: Runs in System Mode, ignores user permissions.
  • Virtual: Allows the class to be extended and methods to be overridden.

Class Methods

  • Define a method with modifiers, return type, input parameters, and body.
  • Syntax: [public | private | protected | global] [override] [static] data_type method_name (input parameters) { // The body of the method }

Constructors

  • Code invoked when an object is created.
  • A default, no-argument constructor is generated if not user-defined.
  • Example:
    public class Order { // The no argument constructor public Order() { // more code implementation here } }

Overloading a Constructor

  • A class can have multiple constructors with different parameters.
  • Constructor chaining uses this(...) syntax.
  • Example:
    public class Order { private static final Integer DEFAULT_SIZE = 10; public String OrderNumber; public Date OrderDate; // Constructor with no arguments public Order() { this(DEFAULT_SIZE); } // Overloaded Constructor public Order(String orderID, Date orderDate) { OrderNumber = orderID; OrderDate = orderDate; } }

Class Components

  • Modifiers: Access level or nature of the class.
  • Class Name: Meaningful name following conventions.
  • Attributes (Fields): Variables representing the class's state.
  • Constructors: Initialize objects.
  • Methods: Define the behaviour of the class.

Initializing and Instantiating Objects

  • Create multiple objects from the same class, each with an independent state.
  • Example:
    Order order1 = new Order(‘ORD-001’, Date.newInstance(2025, 3, 30), 250.00); Order order2 = new Order(‘ORD-002’, Date.newInstance(2025, 3, 31), 150.00); System.debug(order1.orderID); // Outputs: ORD-001 System.debug(order2.orderDate); // Outputs: 2025-03-31 order1.displayOrderDetails(); // Outputs: Order ID: ORD-0001 Order Date: 2025-03-30 Total Amount: 250.00

Message Passing

  • Objects send messages (requests) to other objects (or themselves) to communicate.
  • Components: object name, method name, and parameters.
  • The Order class object communicates with the Product class by sending a request to add a product.

Message Passing Implementation (Apex)

  • Order class has an addProduct(Product product) method that calls the getPrice() method on the Product object.

  • Example:

    // Product Class
    public class Product {
        private String productId;
        private Decimal price;
    // Constructor
        public Product(String productId, Decimal price) {
            this.productId = productId;
            this.price = price;
        }
    // Method to get the price of the product
        public Decimal getPrice() {
            return this.price; // Message passing: responding  with price
        }
    }
    
    // Order Class
    public class Order {
    private String orderId;
    private Decimal totalAmount = 0.0;
    // Constructor
        public Order(String orderId) {
            this.orderId = orderId;
        }
    // Method to add product and update total amount
        public void addProduct(Product product) {
            totalAmount += product.getPrice(); // Message passing:  invoking getPrice() on Product object
        }
    // Method to get the total amount
        public Decimal getTotalAmount() {
            return totalAmount;
        }
    }
    

Hotel Reservation System Example

  • Classes: Guest, Room, and Reservation.
  • Guest: Manages guest information.
  • Room: Represents individual rooms with attributes.
  • Reservation: Ties a guest to a specific room and dates.

Extending Classes

  • Enhance functionality by adding new properties and methods.
  • Example: Adding starRating and amenities to the Hotel class.

Inheritance

  • Subclass reuses attributes and methods of its superclass.
  • Avoids code duplication and allows for extension of existing functionality.

Example: Hierarchical Structure in a Hotel Reservation System

  • A hotel management system with a hierarchical class structure to represent different types of rooms. We start with a base class Room and extend it with specialised room types: Single Room & Double Room.

  • Base class example:

    public class Room {
        public Integer roomNumber;
        public String type;
        public Decimal price;
    // Constructor
        public Room(Integer roomNumber, String type, Decimal price) {
            this.roomNumber = roomNumber;
            this.type = type;
            this.price = price;
        }
    // Method to display room details
        public void displayRoomInfo() {
            System.debug('Room Number: ' + roomNumber);
            System.debug('Type: ' + type);
            System.debug('Price: ' + price);
        }
    }
    
  • Sub class example:

    public class SingleRoom extends Room {
        public Boolean hasSeaView;
    // Constructor
        public SingleRoom(Integer roomNumber, Decimal price, Boolean hasSeaView) {
            super(roomNumber, 'Single', price); // Call superclass constructor
            this.hasSeaView = hasSeaView;
        }
    // Method to display single room details
        public void displaySingleRoomInfo() {
            displayRoomInfo(); // Call method from superclass
            System.debug('Sea View: ' + (hasSeaView ? 'Yes' : 'No'));
        }
    }

Encapsulation

  • Bundling of data and methods into a single unit (class).
  • Restricts direct access to protect the internal state of the object.
  • Example: BankAccount class with private attributes (accountNumber, balance) and public methods (deposit, getBalance).

Getters and Setters

  • Control how attributes are accessed and modified, implementing encapsulation.
  • Getters: Retrieve attribute values.
  • Setters: Update attribute values.
  • Explicit vs. Automatic (Implicit) Getters and Setters.

Polymorphism

  • Objects of different classes can be treated as objects of a common superclass.
  • Achieved through method overriding (runtime polymorphism) and method overloading (compile-time polymorphism).

Run-Time Polymorphism (Method Overriding)

  • Subclass provides a specific implementation of a method defined in its superclass.
  • The method to be executed is determined at runtime based on the object’s actual class.

Compile-Time Polymorphism

  • Method overloading: multiple methods with the same name but different parameters in the same class.
  • Example: Reservation class with overloaded bookRoom methods.

Benefits of Polymorphism

  • Code Reuse
  • Flexibility
  • Maintainability

Practical Applications of OOP (Salesforce)

  • Customer Management: Create and manage customer records with basic attributes.
  • Handling Customer Orders: Manage customer orders with an Order class and establish a relationship with the Customer class.
  • Managing Customer Subscription: Implement a Subscription class to manage customer subscriptions with start and end dates.