# delete all the *.class file in a directory
find . -name "*.class" -type f -delete

SOLID

S - Single Responsibility

Screenshot 2024-09-17 at 08.37.13.png

O - Open/Closed Principle

Screenshot 2024-09-17 at 08.42.26.png

L - Liskov Substitution Principle

// 1. Code Violating LSP

// Base class
public class Account {
    public void deposit(double amount) {}
    public void withdraw(double amount) {}
}

// Subclass: SavingsAccount (LSP Compliant)
public class SavingsAccount extends Account {
    @Override
    public void withdraw(double amount) {}
}

// Subclass: FixedDepositAccount (LSP Violation)
public class FixedDepositAccount extends Account {
    @Override
    public void withdraw(double amount) {
        throw new UnsupportedOperationException("Withdrawals are not allowed in Fixed Deposit Account");
    }
}

// Client code
public class BankService {
    public static void processWithdrawal(Account account, double amount) {
        account.withdraw(amount);
    }

    public static void main(String[] args) {
        SavingsAccount savings = new SavingsAccount();
        processWithdrawal(savings, 100);  // Works fine

        FixedDepositAccount fixedDeposit = new FixedDepositAccount();
        processWithdrawal(fixedDeposit, 100);  // Throws UnsupportedOperationException (LSP Violation)
    }
}

// 2. Correct code adhering to LSP

// Base class for accounts
public abstract class Account {
    public abstract void deposit(double amount);
}

// Interface for accounts that allow withdrawals
public interface Withdrawable {
    void withdraw(double amount);
}

// Subclass: SavingsAccount (Withdrawable)
public class SavingsAccount extends Account implements Withdrawable {
    @Override
    public void deposit(double amount) {}

    @Override
    public void withdraw(double amount) {}
}

// Subclass: FixedDepositAccount (No withdrawals allowed)
public class FixedDepositAccount extends Account {
    @Override
    public void deposit(double amount) {}

    // No withdraw method here, adhering to LSP
}

// Client code
public class BankService {
		
		// Withdrawable object can be replaced by instance of any class
		// that implements this interface 
    public static void processWithdrawal(Withdrawable account, double amount) {
        account.withdraw(amount);
    }

    public static void main(String[] args) {
        SavingsAccount savings = new SavingsAccount();
        processWithdrawal(savings, 100);  // Works fine

        FixedDepositAccount fixedDeposit = new FixedDepositAccount();
        // processWithdrawal(fixedDeposit, 100); // Compile-time error (LSP compliance)
    }
}

// 3. Similarly we can create another class adhering LSP

public class CurrentAccount extends Account implements Withdrawable {
	// Override deposit and withdraw here...
}

// inside BankService
// processWithdrawal can be called on instance of CurrentAccount class as well.
CurrentAccount curr = new CurrentAccount();
processWithdrawal(curr, 100);  // Works fine

I - Interface Segregation Principle

Screenshot 2024-09-17 at 08.51.36.png

Screenshot 2024-09-17 at 08.51.12.png

D - Dependency Inversion Principle

Screenshot 2024-09-17 at 08.58.43.png

Screenshot 2024-09-17 at 08.55.15.png

IS-A and HAS-A relationship

IS-A (Inheritence)

IS-A relationship is implemented using inheritance.

// Superclass
class Vehicle {
    String make;
    String model;

    public Vehicle(String make, String model) {
        this.make = make;
        this.model = model;
    }
}

// Subclass (Car IS-A Vehicle)
class Car extends Vehicle {
    int numberOfDoors;

    public Car(String make, String model, int numberOfDoors) {
        super(make, model); // Inherit from Vehicle
        this.numberOfDoors = numberOfDoors;
    }
}

HAS-A (Composition)

// Component class (Engine)
class Engine {
    int horsepower;
    String type;

    public Engine(int horsepower, String type) {
        this.horsepower = horsepower;
        this.type = type;
    }
}

// Class that HAS-A Engine
class Car {
    String make;
    String model;
    Engine engine; // Composition: Car HAS-A Engine

    public Car(String make, String model, Engine engine) {
        this.make = make;
        this.model = model;
        this.engine = engine;
    }
}

Design Patterns