# Object Oriented Programming (OOP) - Interface vs Abstraction (Java/Kotlin)

\[[Cover Image by](https://unsplash.com/photos/time-lapse-photography-of-city-building-b0eg-PYGICQ) [: Rafael de Nadai](https://unsplash.com/@andandoporai)**\]**

[In the world](https://unsplash.com/@rickpekar) of programming, two key concepts often come up: `Interface` and `Abstraction`. Both are fundamental to *object-oriented programming (OOP)* and play crucial roles in designing robust and maintainable software systems.

In this article, we'll understand the differences between `Interface` and `Abstraction`, explore various scenarios where they are used, and provide examples in both *Kotlin* and *Java*.

## Key differences between Interface and Abstraction:

| Aspect | Interface | Abstraction |
| --- | --- | --- |
| Definition | Specifies a set of methods that a class must implement. | Hides the implementation details and provides a common interface. |
| Implementation | Implemented by classes using the `implements` keyword. | Implemented by abstract classes using the `abstract` keyword. |
| Multiple | Supports multiple inheritance. | Supports single inheritance. |
| Members | Can contain only method signatures and constants. | Can contain both method declarations and concrete methods. |
| Purpose | Defines a contract for classes to adhere to. | Provides a blueprint for subclasses to follow. |

Now, let's explore scenarios where each concept shines.

## Usage Scenarios:

### `Interface`:

1. **Plugin Architecture**: Imagine we're building a text editor application that supports various plugins for different functionalities like syntax highlighting, spell checking, and auto-completion. By defining interfaces like `SyntaxHighlighter`, `SpellChecker`, and `AutoCompleter`, we can ensure that any plugin adhering to these interfaces seamlessly integrates with our editor.
    
    ```kotlin
    interface SyntaxHighlighter {
        fun highlight(text: String): String
    }
    
    // Usage
    class JavaSyntaxHighlighter : SyntaxHighlighter {
        override fun highlight(text: String): String {
            // Implement Java syntax highlighting
        }
    }
    ```
    
    ```java
    interface SpellChecker {
        boolean check(String text);
    }
    
    // Usage
    class EnglishSpellChecker implements SpellChecker {
        @Override
        public boolean check(String text) {
            // Implement English spell checking
        }
    }
    ```
    
2. **Testing Frameworks**: When building test suites, interfaces are must. For instance, in a unit testing framework, we might define an interface `Test` with a method `run()` to execute the test cases. This allows different types of tests (e.g., *unit tests*, *integration tests*) to be executed uniformly.
    
    ```kotlin
    interface Test {
        fun run(): Boolean
    }
    
    // Usage
    class UnitTest : Test {
        override fun run(): Boolean {
            // Implement unit test logic
        }
    }
    ```
    

### `Abstraction`:

1. **Vehicle Simulation**: Let's say we're simulating a traffic system where various vehicles operate. We could have an abstract class `Vehicle` with common attributes and methods such as `accelerate()` and `brake()`. Each specific vehicle type, like `Car` or `Truck`, extends this abstract class and provides its implementation.
    
    ```kotlin
    abstract class Vehicle {
        var speed: Double = 0.0
    
        abstract fun accelerate()
        abstract fun brake()
    }
    
    // Usage
    class Car : Vehicle() {
        override fun accelerate() {
            // Implement car acceleration
        }
    
        override fun brake() {
            // Implement car braking
        }
    }
    ```
    
    ```java
    abstract class Vehicle {
        double speed = 0.0;
    
        abstract void accelerate();
        abstract void brake();
    }
    
    // Usage
    class Car extends Vehicle {
        @Override
        void accelerate() {
            // Implement car acceleration
        }
    
        @Override
        void brake() {
            // Implement car braking
        }
    }
    ```
    
2. **Shape Hierarchy**: Consider a scenario where we're modeling different shapes in a graphics application. We can create an abstract class `Shape` with methods like `calculateArea()` and `draw()`. Concrete shape classes like `Circle` or `Rectangle` extend this abstract class and provide their specific implementations.
    
    ```kotlin
    abstract class Shape {
        abstract fun calculateArea(): Double
        abstract fun draw()
    }
    
    // Usage
    class Circle : Shape() {
        override fun calculateArea(): Double {
            // Implement circle area calculation
        }
    
        override fun draw() {
            // Implement circle drawing
        }
    }
    ```
    
    ```java
    abstract class Shape {
        abstract double calculateArea();
        abstract void draw();
    }
    
    // Usage
    class Circle extends Shape {
        @Override
        double calculateArea() {
            // Implement circle area calculation
        }
    
        @Override
        void draw() {
            // Implement circle drawing
        }
    }
    ```
    

## Conclusion:

In summary,

While both `Interface` and `Abstraction` are essential concepts in *OOP*, they serve distinct purposes. ***Interfaces*** define contracts for classes to adhere to, facilitating polymorphism and code re-usability. On the other hand, ***abstractions*** hide implementation details and provide blueprints for sub-classes to follow, promoting code organization and maintainability.

Understanding when and how to use each concept is crucial for building scalable and maintainable software systems. By leveraging `Interface` and `Abstraction` effectively, developers can design robust, flexible, and modular applications.

---

That's it for today. Happy coding...

%%[buymeacoffee-donate]
