如何解决“实施限制:特征......访问受保护的方法......在具体的特征方法中。”
Posted
技术标签:
【中文标题】如何解决“实施限制:特征......访问受保护的方法......在具体的特征方法中。”【英文标题】:How to solve "Implementation restriction: trait ... accesses protected method ... inside a concrete trait method." 【发布时间】:2013-07-07 13:56:39 【问题描述】:我正在使用的 Java 库类声明
protected getPage(): Page ...
现在我想制作一个辅助 Scala mixin 来添加我经常使用的功能。我不想扩展这个类,因为Java类有不同的子类我想在不同的地方扩展。问题是,如果我在我的 mixin trait
中使用 getPage()
,我会收到此错误:
实现限制:trait
MyMixin
在具体的 trait 方法中访问受保护的方法getPage
。
有没有办法让它工作而不影响我的子类?为什么会有这个限制?
到目前为止,我想出了一个解决方法:我将 trait 中的方法重写为
override def getPage(): Page = super.getPage();
这似乎可行,但我并不完全满意。幸运的是,我不需要在我的子类中覆盖 getPage()
,但如果需要,我会获得相同方法的两个覆盖,但这种解决方法将不起作用。
【问题讨论】:
【参考方案1】:问题在于,即使 trait 扩展了 Java 类,实现实际上并不是在扩展 Java 类的东西中。考虑
class A def f = "foo"
trait T extends A def g = f + "bar"
class B extends T def h = g + "baz"
在我们看到的B
的实际字节码中
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
的子类调用的。
现在,使用 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
有效。
【讨论】:
谢谢,这是我想避免的,将访问器添加到我的子类中。但现在我明白为什么不可能了。 @PetrPudlák - 您不必将访问器添加到 每个 子类,只需添加到 一个 启用访问器的原始子类。然后,所有其他混入特征的类将扩展访问器启用类而不是原始类。 (当然,受保护的访问器将成为接口的一部分,但至少您只需编写一次。) 问题是我想将 trait 混合到 Java 类中,其唯一的公共超类在 Java 库中。这就是为什么我想使用 mixin trait 来添加功能,而不必为我扩展的每个 Java 类创建一个 Scala 子类。 @PetrPudlák - 啊。好吧,反射(在没有限制性安全管理器的环境中)将允许它。选择方法,调用.setAccessible(true)
,invoke
它,转换为正确的类型。我根本不推荐这个。以上是关于如何解决“实施限制:特征......访问受保护的方法......在具体的特征方法中。”的主要内容,如果未能解决你的问题,请参考以下文章