다형성 - 역할과 구현 예제 3
다형성을 활용하면 역할과 구현을 분리해서, 클라이언트 코드의 변경 없이 구현 객체를 변경할 수 있습니다.
다음 관계에서 Driver가 클라이언트입니다.
예제를 통해서 자세히 알아봅시다.

앞서 설명한 자동차 예제를 코드로 구현해보겠습니다.
-
Driver: 운전자는 자동차(Car)의 역할에만 의존합니다.- 구현인 K3, Model3 자동차에 의존하지 않습니다.
-
Driver클래스는Car car멤버 변수를 가집니다. 따라서Car인터페이스를 참조합니다. - 인터페이스를 구현한
K3Car,Model3Car에 의존하지 않고,Car인터페이스에만 의존합니다.- 여기서 설명하는 의존은 클래스 의존 관계를 뜩합니다. 클래스 상에서 어떤 클래스를 알고 있는가를 뜻합니다.
-
Driver클래스 코드를 보면Car인터페이스만 사용하는 것을 확인할 수 있습니다.
-
- 여기서 설명하는 의존은 클래스 의존 관계를 뜩합니다. 클래스 상에서 어떤 클래스를 알고 있는가를 뜻합니다.
-
- 구현인 K3, Model3 자동차에 의존하지 않습니다.
-
Car: 자동차의 역할이고 인터페이스입니다.K3Car,Model3Car클래스가 인터페이스를 구현합니다.
package poly.car1;
public interface Car {
void startEngine();
void offEngine();
void pressAccelerator();
}
package poly.car1;
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");
}
}
package poly.car1;
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");
}
}
package poly.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();
}
}
-
Driver는 멤버 변수로Car car를 가집니다. -
setCar(Car car): 멤버 변수에 자동차를 설정합니다.- 외부에서 누군가 이 메서드를 호출해주어야
Driver는 새로운 자동차를 참조하거나 변경할 수 있습니다.
- 외부에서 누군가 이 메서드를 호출해주어야
-
drive():Car인터페이스가 제공하는 기능들을 통해 자동차를 운전합니다.
package poly.car1;
public class CarMain1 {
public static void main(String[] args) {
Driver driver = new Driver();
// 차량 선택(k3)
K3Car k3Car = new K3Car();
driver.setCar(k3Car);
driver.drive();
// 차량 변경(k3 -> model3)
Model3Car model3Car = new Model3Car();
driver.setCar(model3Car);
driver.drive();
}
}
실행 결과
자동차를 설정합니다: poly.car1.K3Car@4a574795
자동차를 운전합니다.
K3Car.startEngine
K3Car.pressAccelerator
K3Car.offEngine
자동차를 설정합니다: poly.car1.Model3Car@23fc625e
자동차를 운전합니다.
Model3Car.startEngine
Model3Car.pressAccelerator
Model3Car.offEngine

- 먼저
Driver와K3Car를 생성합니다. -
driver.setCar(k3Car)를 호출해서Driver의Car car필드가K3Car의 인스턴스를 참조하도록 합니다. -
driver.drive()를 호출하면x001을 참조합니다.-
car필드가Car타입이므로Car타입을 찾아서 실행하지만 메서드 오버라이딩에 의해K3Car의 기능이 호출됩니다.
-

-
Model3Car를 생성합니다. -
driver.setCar(model3Car)를 호출해서Driver의Car car필드가Model3Car의 인스턴스를 참조하도록 변경합니다. -
driver.drive()를 호출하면x002을 참조합니다.-
car필드가Car타입이므로Car타입을 찾아서 실행하지만 메서드 오버라이딩에 의해Model3Car의 기능이 호출됩니다.
-