문제
저는 제3자 프레임워크로 작업하고 있는데 그 개체 중 일부를 내 클래스 중 하나에 대한 대리자로 래핑해야 한다는 것이 밝혀졌습니다.
class Foo { // 3rd party class.
protected void method() {}
}
class FooWrapper extends Foo {
private Foo mDelegate;
public FooWrapper(Foo inDelegate) {
mDelegate = inDelegate;
}
protected void method() {
mDelegate.method(); // error can't access protected method() of mDelegate
}
}
그래서 문제가 있습니다.이 메서드를 내부 개체에 위임해야 하지만 해당 개체는 보호되어 있으므로 액세스할 수 없습니다.
이 특정 문제를 해결하는 방법에 대한 아이디어가 있습니까?이는 Java 1.3용입니다.
해결책
왜 별도의 foo 인스턴스를 구성 하는가? Foowrapper는 이미 foo입니다.
class Foo {
protected void method() {}
}
class FooWrapper extends Foo {
protected void method() {
super.method();
}
}
편집하다: 실제로 별도의 인스턴스가 있어야한다면 한 가지 방법 (약간 추악하지만)은 반사를 사용하는 것입니다.
public class Foo {
protected void method() {
System.out.println("In Foo.method()");
}
}
public class FooWrapper extends Foo {
private Foo foo;
public FooWrapper(Foo foo) {
this.foo = foo;
}
public void method() {
try {
Method m = foo.getClass().getDeclaredMethod("method", null);
m.setAccessible(true);
m.invoke(foo, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
edit2 : 아래의 의견을 바탕으로 FOO의 두 가지 하위 클래스를 가지고 있습니다. 하나는 단순히 보호 된 방법의 공개 버전과 모든 중요한 방법을 무시한 것입니다. 첫 번째는 Foo처럼 보이고 행동 할 것입니다. 두 번째는 필요한 모든 것을 할 수 있습니다.
public class Foo {
protected void method() {
System.out.println("In Foo.method()");
}
}
public class DelegateFoo extends Foo {
public void method() {
super.method();
}
}
public class FooWrapper extends Foo {
private DelegateFoo foo;
public FooWrapper(DelegateFoo foo) {
this.foo = foo;
}
public void method() {
foo.method();
/* extra logic here */
}
}
다른 팁
내가 이런 상황에 처했을 때 내가 한 일은 좋지 않지만 효과가 있지만 Foo와 같은 패키지 (그러나 소스에서)에서 foo를 확장하고 재정의하는 것입니다. 보호 된 방법을 공개합니다.
이제 FoOwRapper는 Publicfoo를 확장하고 원하는대로 할 수 있습니다.
그러나 원래 항아리에 서명 및 밀봉 된 경우 서명을 배치하기 전에 서명을 제거해야합니다. (항아리의 매니페스트 디렉토리로 이동하여 인증서를 간단히 삭제할 수 있습니다)
글쎄, 해당 속성(게터 또는 공용 변수)에 대한 공개 액세스가 있는 경우 복사 생성자를 만들 수 있습니다.
public FooWrapper(Foo inDelegate) {
this.property1 = inDelegate.getProperty1();
this.property2 = inDelegate.getProperty2();
// for every property
}
속성이 객체인 경우...훌륭하고 더 좋습니다. 그러면 원본 개체를 통해 액세스할 때 변경한 내용도 표시되기 때문입니다!(즉, String과 같은 불변 클래스의 경우 해당 객체 중 하나를 대체해야 합니다.)
서브 클래스 액세스 권한이 있어야합니다 슈퍼 클래스의 보호 방법에.
mdelegate.method () 대신 super.method ()을 호출하면 이동합니다. 둘 다 부모 클래스를 감싸고 있습니다 그리고 그것을 인스턴스화합니다.