문제

저는 제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 ()을 호출하면 이동합니다. 둘 다 부모 클래스를 감싸고 있습니다 그리고 그것을 인스턴스화합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top