extends
& @Overide
public class TurboPlane extends Plane implements Turbo
⇒ TurboPlane 타입의 객체는 Plane/Turbo 타입도 될 수 있고, 두 타입에 정의된 모든 기능을 제공함클래스 상속을 통해 이루어짐
상위 클래스에 정의된 기능을 재사용하기 위한 목적으로 사용
구현을 재사용하면서 다형성도 함께 제공
public class TurboPlane extends Plane {
public void fly() { // Plane에 정의된 fly()구현을 오버라이딩
...
}
}
Plane p = new TurboPlane();
p.fly(); // 실제 p의 타입인 TurboPlane의 fly() 실행
예시를 통해 알아보자.
FileDataReader와 SocketDataReader의 if-else 블록의 코드 구성이 비슷하다
⇒ 추상타입인 ByteSource 타입을 도입하자.
ByteSource의 종류가 변경되더라도 FlowController가 바뀌지 않도록 하자
첫 번째 방법을 활용해보자.
추상화 과정을 통해 얻은 두 가지 유연함
정리
// 흐름 제어 객체
public class FlowController {
private ByteSource byteSource;
public FlowController(ByteSource byteSource) {
this.byteSource = byteSource;
}
public void process() {
byte[] data = byteSource.read();
// ...
}
public void testProcess() {
ByteSource mockSource = new MockByteSource();
FlowController fc = new FlowController(mockSource);
fc.process();
// 결과가 정상적으로 만들어졌는지 확인하는 코드
}
// 보통 Mock객체를 위한 클래스를 별도로 만들기보다는 Mockito나 jmock과 같은 프레임워크를 이용해 Mock 객체 생성함
class MockByteSource implements ByteSource {
public byte[] read() {
byte[] data = new byte[128];
// data를 테스트 목적의 데이터로 초기화
return data;
}
}
}