<aside> 1️⃣ 인터페이스 방식을 사용하는 이유
</aside>
<aside> 2️⃣ 다형성
</aside>
public interface Animal {
void sound();
}
public class Dog implements Animal {
@Override
public void sound() {
System.out.println("Woof!");
}
}
public class Cat implements Animal {
@Override
public void sound() {
System.out.println("Meow!");
}
}
Animal
인터페이스는 **sound
**라는 메서드를 정의하고 있다. 이는 모든 동물이 소리를 내는 것을 추상화한 것이다. Dog
와 Cat
클래스는 이 Animal
인터페이스를 구현(implements)하고, 각자의 방식으로 sound
메서드를 오버라이드(@Override)
한다. 이렇게 하면, 같은 Animal
인터페이스를 가지고(구현하고) 있지만 **Dog
**와 **Cat
**은 각자 다른 소리를 낼 수 있다.public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.sound(); // Prints "Woof!"
myCat.sound(); // Prints "Meow!"
}
}
myDog
**와 **myCat
**은 모두 Animal
타입의 참조 변수이지만, 각각 **Dog
**와 **Cat
**의 인스턴스를 참조하고 있다. 이 때 sound
메서드를 호출하면, 참조하고 있는 실제 객체의 sound
메서드가 호출된다. 이렇게 인터페이스를 통해 서로 다른 동작을 하는 객체를 동일하게 다룰 수 있게 되는 것이 다형성이다. 이로 인해 코드는 보다 유연해지고 확장성을 가지게 된다.<aside> 3️⃣ 개방-폐쇄 원칙(OCP)
</aside>
Product
클래스와 정렬을 수행하는 ProductSorter
클래스가 있다.public class Product {
private String name;
private double price;
// constructors, getters and setters...
}
public class ProductSorter {
public List<Product> sortByPrice(List<Product> products) {
// sort products by price and return
}
}
ProductSorter
**에 sortByName
메서드를 추가할 수 있다. 하지만 이렇게 되면 **ProductSorter
**는 계속해서 변경되어야 한다. 이런 방식은 OCP를 위반하게 되는것이다.
OCP를 적용하기 위해, 우선 정렬 방식을 인터페이스로 추상화시키자// 인터페이스를 만들어서 추상화시켰다.
public interface ProductSortStrategy {
List<Product> sort(List<Product> products);
}
public class PriceSortStrategy implements ProductSortStrategy {
@Override
public List<Product> sort(List<Product> products) {
// sort by price and return
}
}
public class NameSortStrategy implements ProductSortStrategy {
@Override
public List<Product> sort(List<Product> products) {
// sort by name and return
}
}
ProductSorter
**에서 사용하도록 변경한다.