如何解决“实现限制:特征...访问受保护的方法...在具体特征方法内。”

2024-04-28

我正在使用的 Java 库类声明

protected getPage(): Page { ... }

现在我想做一个助手 Scala mixin 来添加我经常使用的功能。我不想扩展该类,因为 Java 类有不同的子类,我想在不同的地方扩展。问题是如果我使用getPage()在我的混音中trait,我收到此错误:

实现限制:特质MyMixin访问受保护的方法getPage在具体的特征方法中。

有没有办法让它工作,而不影响我的子类?为什么会有这个限制?


到目前为止,我想出了一个解决方法:我将特征中的方法重写为

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

这似乎有效,但我并不完全满意。幸运的是我不需要覆盖getPage()在我的子类中,但如果我需要,我会得到同一方法的两次重写,并且此解决方法将不起作用。


问题是,即使特征扩展了 Java 类,但实现实际上并不是在扩展 Java 类的东西中。考虑

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

在实际的字节码中B we see

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

这意味着它只是转发到名为T$class,结果是

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

所以代码的主体不是从子类调用的A at all.

现在,对于 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.

请注意最后一行。

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

works.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何解决“实现限制:特征...访问受保护的方法...在具体特征方法内。” 的相关文章

随机推荐