결론: 기존 코드 수정 없이 새로운 기능을 추가할 수 있어야 함.
1) 인터페이스
public interface Car {
void startEngine();
void offEngine();
void pressAccelerator();
}
2) 인터페이스 구현
public class K3Car implements Car {
@Override
public void startEngine() {
System.out.println("K3Car.startEngine");
}
@Override
public void offEngine() {
System.out.println("K3car.offEngine");
}
@Override
public void pressAccelerator() {
System.out.println("K3car.pressAccelerator");
}
}
-----------------
public class Model3Car implements Car {
@Override
public void startEngine() {
System.out.println("Model3Car.startEngine");
}
@Override
public void offEngine() {
System.out.println("Model3Car.offEngine");
}
@Override
public void pressAccelerator() {
System.out.println("Model3Car.pressAccelerator");
}
}
3) 인터페이스 사용하는 클라이언트 클래스
package personal.polymorphism.car1;
public class Driver {
private Car car; //자동차만 알고 있음
public void setCar(Car car) {
System.out.println("자동차를 설정합니다 :" + car);
this.car = car;
}
public void drive() {
System.out.println("자동차를 운전합니다");
car.startEngine();
car.pressAccelerator();
car.offEngine();
// car 타입으로 호출 -> 안에 있는 오버라이딩된 자식(k3car이나 modelcar)이 호출됨
}
}
코드 실행
package personal.polymorphism.car1;
public class CarMain1 {
public static void main(String[] args) {
Driver driver = new Driver();
//차량 선택(k3)
K3Car k3Car = new K3Car();//새로운 참조주소
// Car car = K3Car; // 부모는 자식을 받을 수 있다!!
// driver.setCar(Car car = k3Car); -> 부모는 자식을 받고 이걸 driver의 멤버변수에 딱 세팅
driver.setCar(k3Car); // 처음엔 null이었지만 이젠 k3Car 객체가 들어옴
driver.drive();
//차량 변경(k3 -> model3)
Model3Car model3Car = new Model3Car(); //새로운 참조주소
driver.setCar(model3Car);
driver.drive();
//차량 변경(model3 -> newCar)
NewCar newCar = new NewCar();
driver.setCar(newCar);
driver.drive();
/*
차량을 추가해도 코드가 돌아가서 driver코드를 수정하지 않아도 됨-> 바로 이것이 OCP
Car 인터페이스 사용하는 클라이언트 driver도 자유롭게 호출 가능 -> 확장이 열려있다.
당연히 수정은 해야함(new 해야하니까)
- 변하지 않는 부분 : 클라이언트 driver 클래스의 코드 변경없이 자동차 확장가능
- 변하는 부분: main() 에서 추가되는 부분
다형성을 활용하고 역할/구현 잘 분리해서 새로운 자동차 추가해도 핵심 코드 유지가능
driver-car 관계가 가장 중요하다!! driver가 변경안되는것도 중요
[전략 패턴]
이 코드가 전략 패턴이다.
car 인터페이스 : 전략을 정의하는 인터페이스
각각 차량 : 전략의 구체적인 구현
전략을 클라이언트 driver 의 변경 없이 교체 가능.
*/
}
}
새로운 차량을 추가해도 driver의 코드는 전혀 변하지않음.