我正在使用的 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(使用前将#替换为@)