Pet*_*lák 6 scala compiler-errors protected traits mixins
我正在使用的Java库类声明
protected getPage(): Page { ... }
Run Code Online (Sandbox Code Playgroud)
现在我想帮助Scala mixin添加我经常使用的功能.我不想扩展类,因为Java类有不同的子类我想在不同的地方扩展.问题是,如果我getPage()在我的mixin中使用trait,我会收到此错误:
实现限制:trait
MyMixin访问getPage具体特征方法中的受保护方法.
有没有一个解决方案如何让它工作,而不影响我的子类?为什么会有这种限制?
到目前为止,我提出了一个解决方法:我将特征中的方法覆盖为
override def getPage(): Page = super.getPage();
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但我并不完全满意.幸运的是,我不需要getPage()在我的子类中覆盖,但是如果我需要,我将获得相同方法的两个覆盖,并且这种解决方法将无法工作.
Rex*_*err 10
问题是即使特性扩展了Java类,实现实际上并不是扩展Java类的东西.考虑
class A { def f = "foo" }
trait T extends A { def g = f + "bar" }
class B extends T { def h = g + "baz" }
Run Code Online (Sandbox Code Playgroud)
在B我们看到的实际字节码中
public java.lang.String g();
  Code:
   0:   aload_0
   1:   invokestatic    #17; //Method T$class.g:(LT;)Ljava/lang/String;
   4:   areturn
Run Code Online (Sandbox Code Playgroud)
这意味着它只是转发给被召唤的东西T$class,事实证明它是
public abstract class T$class extends java.lang.Object{
public static java.lang.String g(T);
  Code:
  ...
Run Code Online (Sandbox Code Playgroud)
因此,代码的主体根本不会从子类中调用A.
现在,使用Scala没有问题,因为它只是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.
Run Code Online (Sandbox Code Playgroud)
注意最后一行.
class WithAccessor extends JavaProtected { protected def myAccessor = getInt }
trait T extends WithAccessor { def i = myAccessor }
Run Code Online (Sandbox Code Playgroud)
作品.
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           1403 次  |  
        
|   最近记录:  |