2013-07-09 2 views
5

자바 라이브러리 클래스는해결 방법 "구현 제한 : 특성 ... 보호 된 메서드 ... 콘크리트 특성 메서드 내부에 액세스합니다." 내가 사용

protected getPage(): Page { ... } 

지금 내가 자주 사용하는 기능을 추가 도우미 스칼라 믹스 인을 만들고 싶어 선언합니다. Java 클래스에는 다른 장소에서 확장하려는 여러 하위 클래스가 있으므로 클래스를 확장하고 싶지 않습니다.

Implementation restriction: trait MyMixin accesses protected method getPage inside a concrete trait method.

내 서브 클래스에 영향을주지 않고, 그것을 작동하게하는 방법을 해결책이 있습니까 : 문제는 내가 내 믹스 인 traitgetPage()를 사용하는 경우, 나는이 오류가 있다는 것입니다? 그리고 왜이 제한이 있습니까?


지금까지, 나는 해결 방법 내놓았다 : 나는

override def getPage(): Page = super.getPage(); 

이 작동하는 것 같다 같은 특성의 메소드를 오버라이드 (override),하지만 난 완전히 만족하지 않다. 운 좋게도 서브 클래스에서 getPage()을 재정의 할 필요는 없지만 필요한 경우 동일한 메소드를 두 번 재정의 할 수 있습니다.이 해결 방법은 작동하지 않습니다.

답변

8

특성은 Java 클래스를 확장하더라도 구현은 실제로 Java 클래스를 확장하는 것이 아닙니다. 바로 전달이 밝혀 T$class라는 뭔가에 그것을 의미 그래서

public abstract class T$class extends java.lang.Object{ 
public static java.lang.String g(T); 
    Code: 
    ... 

의 몸이다 우리가

public java.lang.String g(); 
    Code: 
    0: aload_0 
    1: invokestatic #17; //Method T$class.g:(LT;)Ljava/lang/String; 
    4: areturn 

를 참조 B의 실제 바이트 코드에서

class A { def f = "foo" } 
trait T extends A { def g = f + "bar" } 
class B extends T { def h = g + "baz" } 

을 고려 코드는 A의 하위 클래스에서 전혀 호출되지 않습니다.

이제 스칼라에서는 바이트 코드에서 protected 플래그가 생략되었으므로 아무런 문제가 없습니다. 그러나 Java은 하위 클래스 만 보호 된 메서드를 호출 할 수 있도록합니다.

따라서 문제와 메시지가 있습니다.

오류 메시지가 아마도 가장 좋은 대안이 무엇인지 알 수 있지만 쉽게이 문제를 해결받을 수 없습니다 :

public class JavaProtected { 
    protected int getInt() { return 5; } 
} 

scala> trait T extends JavaProtected { def i = getInt } 
<console>:8: error: Implementation restriction: trait T accesses 
     protected method getInt inside a concrete trait method. 
    Add an accessor in a class extending class JavaProtected as a workaround. 

참고 마지막 줄.

class WithAccessor extends JavaProtected { protected def myAccessor = getInt } 
trait T extends WithAccessor { def i = myAccessor } 

작품입니다.

+0

내 서브 클래스에 접근자를 추가하는 것을 피하고 싶습니다. 그러나 지금 나는 왜 그것이 가능하지 않은지 이해한다. –

+0

@ PetrPudlák - _every_ 하위 클래스에 접근자를 추가 할 필요없이 원본의 _ 접근 _ 가능 하위 클래스 만 추가하면됩니다. 그런 다음 특성에서 혼합되는 다른 모든 요소는 원본 대신 접근 자 사용 가능 클래스를 확장합니다. 물론 보호 된 접근자는 인터페이스에 포함되지만 최소한 한 번만 작성하면됩니다. –

+0

문제는 공통된 상위 클래스 만있는 Java 클래스에 특성을 혼합하려고합니다. 자바 라이브러리.이것이 제가 확장 한 각각의 자바 클래스를위한 스칼라 서브 클래스를 만들지 않고도 기능을 추가하기 위해 mixin 특성을 사용하고자했던 이유입니다. –