Interfaces and Callbacks

Let's take this step by step to understand interfaces in Object-Oriented Programming (OOP) and how they are used in callbacks with synchronous programming, using a detailed calculator program example.


Step 1: Understanding Interfaces

An interface is like a blueprint for a class. It specifies a contract that a class must follow. The interface itself does not provide any implementation for its methods; it only defines the method signatures. Classes that implement the interface provide the actual implementation.

Key Points About Interfaces:

  1. Defines a Contract: An interface declares methods that implementing classes must define.

  2. No Implementation: Interfaces cannot have method bodies (until Java 8, which allows default methods).

  3. Decoupling: Interfaces help in creating loosely coupled systems, as a class only needs to know about the interface, not the specific implementation.

Example of an Interface:

interface CalculatorListener {
    void onResultCalculated(int result);
}
  • This interface declares a single method onResultCalculated, which any implementing class must provide.


Step 2: Why Use Interfaces?

  1. Flexibility: Interfaces allow different classes to implement the same behavior in their unique ways.

  2. Callback Mechanism: Interfaces enable one class to notify another class when a task is completed (like an event listener).


Step 3: Concept of Callback Using Interfaces

A callback is a mechanism where one object communicates with another by invoking a method defined in the other object. For example:

  • Caller Class performs some operation and then invokes a method on the Listener Class.

  • The Listener Class provides specific behavior by implementing the interface.


Step 4: Calculator Program with Callback

We will create a simple calculator program that:

  1. Accepts two numbers and an operation (addition).

  2. Uses a callback mechanism to notify when the calculation is complete.


Step-by-Step Implementation

1. Define the Interface

The interface defines the contract for the callback.

  • This interface declares a method onResultCalculated to notify when the result is ready.


2. Create the Caller Class (Calculator)

This class performs the calculation and triggers the callback.

  • registerCalculatorListener: Registers a listener object (implementing CalculatorListener).

  • add: Performs addition and then invokes the callback method onResultCalculated.


3. Create the Listener Class (CalculatorApp)

This class implements the CalculatorListener interface and defines the callback behavior.

  • onResultCalculated: Defines what happens when the result is ready (prints it).


4. Main Method (Driver Code)

This sets up the interaction between Calculator and CalculatorApp.


Flow of Execution

  1. Create Objects:

    • Calculator performs calculations.

    • CalculatorApp listens for results.

  2. Register Listener:

    • The CalculatorApp object is registered as a listener using registerCalculatorListener.

  3. Perform Addition:

    • Calculator.add(5, 3) calculates the sum.

    • After calculation, onResultCalculated in CalculatorApp is invoked with the result.


Step 5: Output

When you run the program, the output will be:


Step 6: Concept Explained

  1. Interface as a Contract:

    • CalculatorListener defines the method onResultCalculated, ensuring any class that implements it provides the behavior for the callback.

  2. Callback Mechanism:

    • Calculator performs the operation and invokes the callback method on the registered listener (CalculatorApp).

  3. Synchronous Programming:

    • The callback (onResultCalculated) is invoked immediately after the calculation, making it synchronous.


Step 7: Advantages of Using Callbacks

  1. Decoupling: Calculator does not need to know about the implementation details of CalculatorApp.

  2. Flexibility: You can register different listeners with different behaviors.

  3. Extensibility: New functionality can be added by creating new listener implementations.


Step 8: Interactive Summary

Imagine the Calculator as a chef in a restaurant and the CalculatorApp as a waiter. The chef performs the task (cooking), and when the food is ready, the waiter (listener) is notified to serve it. The chef doesn’t need to know how the waiter serves the food—that’s the waiter's responsibility.

By using interfaces and callbacks, you can build systems where components communicate efficiently without being tightly coupled.

Let me know if you need further clarification or additional examples!

Last updated