두 개의 인터페이스가 있다고 가정하십시오.
interface Readable {
public void read();
}
interface Writable {
public void write();
}
경우에 따라 구현 객체는 이들 중 하나만 지원할 수 있지만 많은 경우 구현시 두 인터페이스를 모두 지원합니다. 인터페이스를 사용하는 사람들은 다음과 같은 작업을 수행해야합니다.
// can't write to it without explicit casting
Readable myObject = new MyObject();
// can't read from it without explicit casting
Writable myObject = new MyObject();
// tight coupling to actual implementation
MyObject myObject = new MyObject();
이 옵션들 중 어느 것도 매우 편리하지 않으며, 메소드 매개 변수로 원한다고 생각할 때 훨씬 더 편리합니다.
한 가지 해결책은 랩핑 인터페이스를 선언하는 것입니다.
interface TheWholeShabam extends Readable, Writable {}
그러나 이것은 하나의 특정 문제가 있습니다. Readable과 Writable 을 모두 지원하는 모든 구현 은 인터페이스를 사용하는 사람들과 호환되도록하려면 TheWholeShabam을 구현해야합니다. 비록 두 인터페이스의 보장 된 존재 외에는 아무것도 제공하지 않습니다.
이 문제에 대한 깨끗한 해결책이 있습니까? 아니면 랩퍼 인터페이스로 가야합니까?
최신 정보
실제로 읽고 쓸 수있는 객체가 필요한 경우가 많으므로 인수에서 우려를 분리하는 것이 항상 깨끗한 해결책은 아닙니다.
업데이트 2
(답변으로 추출되므로 댓글을 달기가 더 쉽습니다)
업데이트 3
이것에 대한 기본 사용 사례는 스트림 이 아님 을 명심하십시오 (물론 지원되어야하지만). 스트림은 입력과 출력을 매우 구체적으로 구분하며 책임이 명확하게 분리되어 있습니다. 오히려 매우 구체적인 상태가 첨부 된 하나의 객체에 쓰고 읽을 수있는 하나의 객체가 필요한 바이트 버퍼와 같은 것을 생각하십시오. 이 객체들은 비동기 I / O, 인코딩 등과 같은 것들에 매우 유용하기 때문에 존재합니다.
업데이트 4
내가 시도한 첫 번째 것 중 하나는 아래 주어진 제안과 동일했지만 (허용 된 답변을 확인하십시오) 너무 약한 것으로 판명되었습니다.
유형을 반환 해야하는 클래스가 있다고 가정하십시오.
public <RW extends Readable & Writable> RW getItAll();
이 메소드를 호출하면 객체를받는 변수에 의해 일반 RW가 결정되므로이 변수를 설명 할 방법이 필요합니다.
MyObject myObject = someInstance.getItAll();
이것은 작동하지만 다시 한 번 구현에 연결하고 실제로 반환 된 내용에 따라 런타임에 클래스 캐스트 예외를 throw 할 수 있습니다.
또한 유형 RW의 클래스 변수를 원하는 경우 클래스 레벨에서 제네릭을 정의해야합니다.