Practice Code

Problem 1: Encapsulation

Scenario: Create a class BankAccount that encapsulates the balance of a bank account. Provide methods to deposit and withdraw money, ensuring that the balance cannot be set directly.

Problem 2: Inheritance

Scenario: Create a base class Animal with a method makeSound(). Derive two classes Dog and Cat from it, each overriding the makeSound() method.

Problem 3: Polymorphism

Scenario: Create an interface Shape with a method calculateArea(). Implement this interface in two classes Circle and Rectangle.

Problem 4: Abstraction

Scenario: Create an abstract class Vehicle with an abstract method move(). Derive two concrete classes Car and Bicycle from it, each implementing the move() method.

Problem 5: Encapsulation

Scenario: Create a class Person that encapsulates the name, age, and address of a person. Provide appropriate constructors, getters, and setters.

Problem 6: Abstraction

Scenario: Create an abstract class Appliance with an abstract method operate(). Derive two concrete classes WashingMachine and Microwave from it, each implementing the operate() method.

Advanced Problem 1: Encapsulation and Validation

Scenario: Create a class User that encapsulates a username and password. Implement methods to set the username and password with validation (e.g., the password must be at least 8 characters long).

Advanced Problem 2: Inheritance and Interfaces

Scenario: Create a base class Employee and an interface Payable. The Employee class should implement the Payable interface and include subclasses FullTimeEmployee and PartTimeEmployee with their own salary calculation methods.

Code:

javaCopy codeinterface Payable {
    double calculatePay();
}

class Employee implements Payable {
    protected String name;
    protected double baseSalary;

    public Employee(String name, double baseSalary) {
        this.name = name;
        this.baseSalary = baseSalary;
    }

    @Override
    public double calculatePay() {
        return baseSalary;
    }
}

class FullTimeEmployee extends Employee {
    private double bonus;

    public FullTimeEmployee(String name, double baseSalary, double bonus) {
        super(name, baseSalary);
        this.bonus = bonus;
    }

    @Override
    public double calculatePay() {
        return baseSalary + bonus;
    }
}

class PartTimeEmployee extends Employee {
    private int hoursWorked;
    private double hourlyRate;

    public PartTimeEmployee(String name, double hourlyRate, int hoursWorked) {
        super(name, hourlyRate * hoursWorked);
        this.hourlyRate = hourlyRate;
        this.hoursWorked = hoursWorked;
    }

    @Override
    public double calculatePay() {
        return hourlyRate * hoursWorked;
    }
}

public class TestInheritanceAndInterfaces {
    public static void main(String[] args) {
        Employee fullTime = new FullTimeEmployee("John", 50000, 5000);
        Employee partTime = new PartTimeEmployee("Jane", 20, 25);

        System.out.println(fullTime.name + "'s Pay: " + fullTime.calculatePay());
        System.out.println(partTime.name + "'s Pay: " + partTime.calculatePay());
    }
}

Advanced Problem 3: Polymorphism with Overloaded Methods

Scenario: Create a class Calculator that demonstrates method overloading by implementing multiple add methods to handle different types and numbers of parameters.

Code:

javaCopy codepublic class Calculator {

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

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

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

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

    public static void main(String[] args) {
        Calculator calculator = new Calculator();

        System.out.println("Sum of 2 and 3: " + calculator.add(2, 3));
        System.out.println("Sum of 2.5 and 3.5: " + calculator.add(2.5, 3.5));
        System.out.println("Sum of 1, 2, and 3: " + calculator.add(1, 2, 3));
        System.out.println("Sum of 1.5, 2.5, and 3.5: " + calculator.add(1.5, 2.5, 3.5));
    }
}

Advanced Problem 4: Abstraction with Template Method Pattern

Scenario: Create an abstract class Game with a template method playGame(). Implement concrete subclasses Football and Chess with their own specific implementations.

Code:

javaCopy codeabstract class Game {
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();

    // Template method
    public final void playGame() {
        initialize();
        startPlay();
        endPlay();
    }
}

class Football extends Game {

    @Override
    void initialize() {
        System.out.println("Football Game Initialized. Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Football Game Started. Enjoy the game!");
    }

    @Override
    void endPlay() {
        System.out.println("Football Game Finished!");
    }
}

class Chess extends Game {

    @Override
    void initialize() {
        System.out.println("Chess Game Initialized. Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Chess Game Started. Enjoy the game!");
    }

    @Override
    void endPlay() {
        System.out.println("Chess Game Finished!");
    }
}

public class TestTemplateMethod {
    public static void main(String[] args) {
        Game game = new Football();
        game.playGame();
        System.out.println();
        game = new Chess();
        game.playGame();
    }
}

Additional Advanced Problem Ideas:

  1. Encapsulation and Dependency Injection: Create a Car class with encapsulated fields for the engine, wheels, and transmission. Use dependency injection to provide these components.

  2. Inheritance and Abstract Classes: Create a base class Shape with abstract methods calculateArea() and calculatePerimeter(). Extend it with Circle, Rectangle, and Triangle classes, each providing their own implementations.

  3. Polymorphism with Interfaces and Generics: Create a generic interface Repository<T> with methods for adding, removing, and finding items. Implement this interface with InMemoryRepository and DatabaseRepository classes.

  4. Abstraction with Factory Pattern: Create an abstract class AnimalFactory with a method createAnimal(). Implement concrete factories DogFactory and CatFactory that create Dog and Cat objects, respectively.

These advanced problems will further challenge your understanding and application of OOP principles in Java. Good luck with your preparation!

Certainly! Here are four coding problems, each designed to test your understanding of the four principles of Object-Oriented Programming (OOP) in Java: encapsulation, inheritance, polymorphism, and abstraction. Along with each problem, I will provide a sample solution.

Problem 1: Encapsulation

Scenario: Create a class BankAccount that encapsulates the balance of a bank account. Provide methods to deposit and withdraw money, ensuring that the balance cannot be set directly.

Code:

javaCopy codepublic class BankAccount {
    private double balance;

    public BankAccount(double initialBalance) {
        if (initialBalance > 0) {
            this.balance = initialBalance;
        } else {
            this.balance = 0;
        }
    }

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        } else {
            System.out.println("Deposit amount must be positive.");
        }
    }

    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
        } else {
            System.out.println("Invalid withdrawal amount.");
        }
    }

    public static void main(String[] args) {
        BankAccount account = new BankAccount(1000);
        account.deposit(500);
        account.withdraw(200);
        System.out.println("Current balance: " + account.getBalance());
    }
}

Problem 2: Inheritance

Scenario: Create a base class Animal with a method makeSound(). Derive two classes Dog and Cat from it, each overriding the makeSound() method.

Code:

javaCopy codeclass Animal {
    public void makeSound() {
        System.out.println("Some generic animal sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Woof");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Meow");
    }
}

public class TestInheritance {
    public static void main(String[] args) {
        Animal myDog = new Dog();
        Animal myCat = new Cat();
        myDog.makeSound();
        myCat.makeSound();
    }
}

Problem 3: Polymorphism

Scenario: Create an interface Shape with a method calculateArea(). Implement this interface in two classes Circle and Rectangle.

Code:

javaCopy codeinterface Shape {
    double calculateArea();
}

class Circle implements Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle implements Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double calculateArea() {
        return width * height;
    }
}

public class TestPolymorphism {
    public static void main(String[] args) {
        Shape circle = new Circle(5);
        Shape rectangle = new Rectangle(4, 6);

        System.out.println("Circle area: " + circle.calculateArea());
        System.out.println("Rectangle area: " + rectangle.calculateArea());
    }
}

Problem 4: Abstraction

Scenario: Create an abstract class Vehicle with an abstract method move(). Derive two concrete classes Car and Bicycle from it, each implementing the move() method.

Code:

javaCopy codeabstract class Vehicle {
    public abstract void move();
}

class Car extends Vehicle {
    @Override
    public void move() {
        System.out.println("The car drives on the road.");
    }
}

class Bicycle extends Vehicle {
    @Override
    public void move() {
        System.out.println("The bicycle rides on the path.");
    }
}

public class TestAbstraction {
    public static void main(String[] args) {
        Vehicle myCar = new Car();
        Vehicle myBicycle = new Bicycle();
        myCar.move();
        myBicycle.move();
    }
}

Additional Exercise Ideas:

  1. Encapsulation: Create a Student class with fields for name, age, and grade. Ensure proper encapsulation with getters and setters.

  2. Inheritance: Create a Person class and extend it with Student and Teacher classes, each with additional specific attributes and methods.

  3. Polymorphism: Create a base class Employee with a method calculateSalary(). Derive classes Manager and Developer that override this method.

  4. Abstraction: Create an abstract class Appliance with an abstract method turnOn(). Implement this method in WashingMachine and Refrigerator classes.

These problems and solutions should help you prepare for your interview and demonstrate a strong understanding of the four principles of OOP in Java. Good luck!

2/24o

more questions

ChatGPT

Sure! Here are more questions that cover the four principles of OOP (encapsulation, inheritance, polymorphism, and abstraction), each with a scenario and a corresponding Java code solution.

Problem 5: Encapsulation

Scenario: Create a class Person that encapsulates the name, age, and address of a person. Provide appropriate constructors, getters, and setters.

Code:

javaCopy codepublic class Person {
    private String name;
    private int age;
    private String address;

    public Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age > 0) {
            this.age = age;
        } else {
            System.out.println("Age must be positive.");
        }
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public static void main(String[] args) {
        Person person = new Person("Alice", 30, "123 Main St");
        System.out.println("Name: " + person.getName());
        System.out.println("Age: " + person.getAge());
        System.out.println("Address: " + person.getAddress());

        person.setAge(-5); // Invalid age
        person.setAddress("456 Elm St");
        System.out.println("Updated Address: " + person.getAddress());
    }
}

Problem 6: Inheritance

Scenario: Create a base class Employee with fields for name and salary. Derive two classes Manager and Engineer, each with additional fields and methods.

Code:

javaCopy codeclass Employee {
    private String name;
    private double salary;

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    public void work() {
        System.out.println(name + " is working.");
    }
}

class Manager extends Employee {
    private int teamSize;

    public Manager(String name, double salary, int teamSize) {
        super(name, salary);
        this.teamSize = teamSize;
    }

    public void manage() {
        System.out.println(getName() + " is managing a team of " + teamSize);
    }
}

class Engineer extends Employee {
    private String expertise;

    public Engineer(String name, double salary, String expertise) {
        super(name, salary);
        this.expertise = expertise;
    }

    public void develop() {
        System.out.println(getName() + " is developing in " + expertise);
    }
}

public class TestInheritance {
    public static void main(String[] args) {
        Manager manager = new Manager("John", 80000, 10);
        Engineer engineer = new Engineer("Jane", 60000, "Java");

        manager.work();
        manager.manage();

        engineer.work();
        engineer.develop();
    }
}

Problem 7: Polymorphism

Scenario: Create a base class Media with a method play(). Derive two classes Audio and Video, each overriding the play() method.

Code:

javaCopy codeclass Media {
    public void play() {
        System.out.println("Playing media...");
    }
}

class Audio extends Media {
    @Override
    public void play() {
        System.out.println("Playing audio...");
    }
}

class Video extends Media {
    @Override
    public void play() {
        System.out.println("Playing video...");
    }
}

public class TestPolymorphism {
    public static void main(String[] args) {
        Media media1 = new Audio();
        Media media2 = new Video();

        media1.play();
        media2.play();
    }
}

Problem 8: Abstraction

Scenario: Create an abstract class Appliance with an abstract method operate(). Derive two concrete classes WashingMachine and Microwave from it, each implementing the operate() method.

Code:

javaCopy codeabstract class Appliance {
    public abstract void operate();
}

class WashingMachine extends Appliance {
    @Override
    public void operate() {
        System.out.println("The washing machine is washing clothes.");
    }
}

class Microwave extends Appliance {
    @Override
    public void operate() {
        System.out.println("The microwave is heating food.");
    }
}

public class TestAbstraction {
    public static void main(String[] args) {
        Appliance appliance1 = new WashingMachine();
        Appliance appliance2 = new Microwave();

        appliance1.operate();
        appliance2.operate();
    }
}

Additional Problem Ideas:

  1. Encapsulation: Create a LibraryBook class with fields for title, author, and ISBN. Ensure these fields are properly encapsulated.

  2. Inheritance: Create a base class Shape with methods draw() and erase(). Extend it with classes Circle, Square, and Triangle, each with specific implementations.

  3. Polymorphism: Create an interface Vehicle with a method startEngine(). Implement this interface in classes Car, Motorcycle, and Truck.

  4. Abstraction: Create an abstract class Game with an abstract method play(). Derive concrete classes Soccer and Chess from it, each with its own implementation of play().

These additional problems will further solidify your understanding of OOP principles in Java. Good luck with your interview preparation!

4o

more advance

ChatGPT

Sure, let's delve into more advanced scenarios that demonstrate a deeper understanding of OOP principles in Java, including more complex interactions between classes and more detailed coding problems.

Advanced Problem 1: Encapsulation and Validation

Scenario: Create a class User that encapsulates a username and password. Implement methods to set the username and password with validation (e.g., the password must be at least 8 characters long).

Code:

javaCopy codepublic class User {
    private String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        setPassword(password);
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        if (password.length() >= 8) {
            this.password = password;
        } else {
            System.out.println("Password must be at least 8 characters long.");
        }
    }

    public static void main(String[] args) {
        User user = new User("Alice", "password123");
        System.out.println("Username: " + user.getUsername());
        System.out.println("Password: " + user.getPassword());

        user.setPassword("short");
        System.out.println("Password after trying to set a short one: " + user.getPassword());
    }
}

Advanced Problem 2: Inheritance and Interfaces

Scenario: Create a base class Employee and an interface Payable. The Employee class should implement the Payable interface and include subclasses FullTimeEmployee and PartTimeEmployee with their own salary calculation methods.

Code:

javaCopy codeinterface Payable {
    double calculatePay();
}

class Employee implements Payable {
    protected String name;
    protected double baseSalary;

    public Employee(String name, double baseSalary) {
        this.name = name;
        this.baseSalary = baseSalary;
    }

    @Override
    public double calculatePay() {
        return baseSalary;
    }
}

class FullTimeEmployee extends Employee {
    private double bonus;

    public FullTimeEmployee(String name, double baseSalary, double bonus) {
        super(name, baseSalary);
        this.bonus = bonus;
    }

    @Override
    public double calculatePay() {
        return baseSalary + bonus;
    }
}

class PartTimeEmployee extends Employee {
    private int hoursWorked;
    private double hourlyRate;

    public PartTimeEmployee(String name, double hourlyRate, int hoursWorked) {
        super(name, hourlyRate * hoursWorked);
        this.hourlyRate = hourlyRate;
        this.hoursWorked = hoursWorked;
    }

    @Override
    public double calculatePay() {
        return hourlyRate * hoursWorked;
    }
}

public class TestInheritanceAndInterfaces {
    public static void main(String[] args) {
        Employee fullTime = new FullTimeEmployee("John", 50000, 5000);
        Employee partTime = new PartTimeEmployee("Jane", 20, 25);

        System.out.println(fullTime.name + "'s Pay: " + fullTime.calculatePay());
        System.out.println(partTime.name + "'s Pay: " + partTime.calculatePay());
    }
}

Advanced Problem 3: Polymorphism with Overloaded Methods

Scenario: Create a class Calculator that demonstrates method overloading by implementing multiple add methods to handle different types and numbers of parameters.

Code:

javaCopy codepublic class Calculator {

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

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

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

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

    public static void main(String[] args) {
        Calculator calculator = new Calculator();

        System.out.println("Sum of 2 and 3: " + calculator.add(2, 3));
        System.out.println("Sum of 2.5 and 3.5: " + calculator.add(2.5, 3.5));
        System.out.println("Sum of 1, 2, and 3: " + calculator.add(1, 2, 3));
        System.out.println("Sum of 1.5, 2.5, and 3.5: " + calculator.add(1.5, 2.5, 3.5));
    }
}

Advanced Problem 4: Abstraction with Template Method Pattern

Scenario: Create an abstract class Game with a template method playGame(). Implement concrete subclasses Football and Chess with their own specific implementations.

Code:

javaCopy codeabstract class Game {
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();

    // Template method
    public final void playGame() {
        initialize();
        startPlay();
        endPlay();
    }
}

class Football extends Game {

    @Override
    void initialize() {
        System.out.println("Football Game Initialized. Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Football Game Started. Enjoy the game!");
    }

    @Override
    void endPlay() {
        System.out.println("Football Game Finished!");
    }
}

class Chess extends Game {

    @Override
    void initialize() {
        System.out.println("Chess Game Initialized. Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Chess Game Started. Enjoy the game!");
    }

    @Override
    void endPlay() {
        System.out.println("Chess Game Finished!");
    }
}

public class TestTemplateMethod {
    public static void main(String[] args) {
        Game game = new Football();
        game.playGame();
        System.out.println();
        game = new Chess();
        game.playGame();
    }
}

Additional Advanced Problem Ideas:

  1. Encapsulation and Dependency Injection: Create a Car class with encapsulated fields for the engine, wheels, and transmission. Use dependency injection to provide these components.

  2. Inheritance and Abstract Classes: Create a base class Shape with abstract methods calculateArea() and calculatePerimeter(). Extend it with Circle, Rectangle, and Triangle classes, each providing their own implementations.

  3. Polymorphism with Interfaces and Generics: Create a generic interface Repository<T> with methods for adding, removing, and finding items. Implement this interface with InMemoryRepository and DatabaseRepository classes.

  4. Abstraction with Factory Pattern: Create an abstract class AnimalFactory with a method createAnimal(). Implement concrete factories DogFactory and CatFactory that create Dog and Cat objects, respectively.

These advanced problems will further challenge your understanding and application of OOP principles in Java. Good luck with your preparation!

4o

also add solid principle pratical question on this

ChatGPT

Certainly! Here are practical coding problems that incorporate the SOLID principles (Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion) along with their corresponding Java solutions.

Problem 1: Single Responsibility Principle (SRP)

Scenario: Create a Book class with methods to handle the book details and another class to handle book printing.

Code:

javaCopy codeclass Book {
    private String title;
    private String author;
    private String text;

    public Book(String title, String author, String text) {
        this.title = title;
        this.author = author;
        this.text = text;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public String getText() {
        return text;
    }

    // This class should only handle book details, not printing
}

class BookPrinter {
    public void printTextToConsole(String text) {
        // our code for formatting and printing the text to console
        System.out.println(text);
    }

    public void printTextToFile(String text, String filename) {
        // code to print the text to a file
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) {
            writer.write(text);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public class TestSRP {
    public static void main(String[] args) {
        Book book = new Book("Title", "Author", "This is the book text.");
        BookPrinter printer = new BookPrinter();

        printer.printTextToConsole(book.getText());
        printer.printTextToFile(book.getText(), "book.txt");
    }
}

Problem 2: Open/Closed Principle (OCP)

Scenario: Create a Shape class with a method to calculate the area. Extend the functionality by creating specific shape classes without modifying the existing code.

Code:

javaCopy codeabstract class Shape {
    public abstract double calculateArea();
}

class Rectangle extends Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double calculateArea() {
        return width * height;
    }
}

class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

public class TestOCP {
    public static void main(String[] args) {
        Shape rectangle = new Rectangle(5, 4);
        Shape circle = new Circle(3);

        System.out.println("Rectangle area: " + rectangle.calculateArea());
        System.out.println("Circle area: " + circle.calculateArea());
    }
}

Problem 3: Liskov Substitution Principle (LSP)

Scenario: Create a base class Bird and a subclass FlyingBird that extends Bird. Ensure that replacing Bird with FlyingBird does not alter the correctness of the program.

Code:

javaCopy codeclass Bird {
    public void eat() {
        System.out.println("The bird is eating.");
    }
}

class FlyingBird extends Bird {
    public void fly() {
        System.out.println("The bird is flying.");
    }
}

public class TestLSP {
    public static void main(String[] args) {
        Bird bird = new Bird();
        bird.eat();

        Bird flyingBird = new FlyingBird();
        flyingBird.eat();
        ((FlyingBird) flyingBird).fly();  // Safe casting because we know it's a FlyingBird
    }
}

Problem 4: Interface Segregation Principle (ISP)

Scenario: Create an interface Worker with methods work and eat. Separate these methods into different interfaces and implement them in respective classes.

Code:

javaCopy codeinterface Workable {
    void work();
}

interface Eatable {
    void eat();
}

class Worker implements Workable, Eatable {
    @Override
    public void work() {
        System.out.println("Worker is working.");
    }

    @Override
    public void eat() {
        System.out.println("Worker is eating.");
    }
}

class Robot implements Workable {
    @Override
    public void work() {
        System.out.println("Robot is working.");
    }
}

public class TestISP {
    public static void main(String[] args) {
        Worker worker = new Worker();
        worker.work();
        worker.eat();

        Robot robot = new Robot();
        robot.work();
    }
}

Problem 5: Dependency Inversion Principle (DIP)

Scenario: Create a Keyboard and Monitor class. Implement a Computer class that depends on abstractions (interfaces) rather than concrete classes.

Code:

javaCopy codeinterface Keyboard {
    void type();
}

class MechanicalKeyboard implements Keyboard {
    @Override
    public void type() {
        System.out.println("Typing on a mechanical keyboard.");
    }
}

class MembraneKeyboard implements Keyboard {
    @Override
    public void type() {
        System.out.println("Typing on a membrane keyboard.");
    }
}

interface Monitor {
    void display();
}

class LEDMonitor implements Monitor {
    @Override
    public void display() {
        System.out.println("Displaying on an LED monitor.");
    }
}

class LCDMonitor implements Monitor {
    @Override
    public void display() {
        System.out.println("Displaying on an LCD monitor.");
    }
}

class Computer {
    private Keyboard keyboard;
    private Monitor monitor;

    public Computer(Keyboard keyboard, Monitor monitor) {
        this.keyboard = keyboard;
        this.monitor = monitor;
    }

    public void use() {
        keyboard.type();
        monitor.display();
    }
}

public class TestDIP {
    public static void main(String[] args) {
        Keyboard keyboard = new MechanicalKeyboard();
        Monitor monitor = new LEDMonitor();

        Computer computer = new Computer(keyboard, monitor);
        computer.use();
    }
}

Additional Advanced Problem Ideas:

  1. Encapsulation and Builder Pattern: Create a House class with multiple optional parameters. Use the Builder pattern to construct House objects.

  2. Inheritance and Strategy Pattern: Create a base Transport class with a move method. Implement different movement strategies (DriveStrategy, FlyStrategy, SailStrategy) and use them in subclasses.

  3. Polymorphism and Command Pattern: Create an interface Command with an execute method. Implement different command classes (OpenCommand, CloseCommand, SaveCommand) and a CommandExecutor class to execute these commands.

  4. Abstraction and Observer Pattern: Create an abstract Subject class with methods to attach, detach, and notify observers. Implement concrete ConcreteSubject and Observer classes to demonstrate the Observer pattern.

  5. SOLID and Dependency Injection with Spring: Create a Spring-based application demonstrating Dependency Injection, where services and repositories are injected into controllers using annotations.

Last updated