Scala:将特征与私人领域混合
发布时间:2020-12-16 08:50:29 所属栏目:安全 来源:网络整理
导读:这不是一个问题,而是让我感到非常兴奋!我写这个小例子只是为了证明相反 – 我预计编译器错误或其中一个值(111或222,我不确定). scala trait T1 { private val v = 111; def getValueT1 = v }scala trait T2 { private val v = 222; def getValueT2 = v }sca
这不是一个问题,而是让我感到非常兴奋!我写这个小例子只是为了证明相反 – 我预计编译器错误或其中一个值(111或222,我不确定).
scala> trait T1 { private val v = 111; def getValueT1 = v } scala> trait T2 { private val v = 222; def getValueT2 = v } scala> class T12 extends T1 with T2 scala> val t = new T12 scala> t.getValueT1 res9: Int = 111 scala> t.getValueT2 res10: Int = 222 为什么v不会被覆盖?当然,只有vs是私人的,这仍然有效. 解决方法
由于traits不仅仅是接口,它们还需要一些方法来存储它们的内部状态.但它们必须与接口兼容 – 那么他们做了什么?它们为类似于字段的内容创建访问器(正如您可以在类文件中使用javap -l -s -c -private看到的那样)(以及其他内容):
public interface T1 extends java.lang.Object { public abstract int T1$$v(); Signature: ()I public abstract int getValueT1(); Signature: ()I } 然后创建一个具有静态方法来实现该功能的实现类: public abstract class T1$class extends java.lang.Object { public static int getValueT1(T1); Signature: (LT1;)I Code: 0: aload_0 1: invokeinterface #12,1; //InterfaceMethod T1.T1$$v:()I 6: ireturn } 现在,希望很明显这些内容默认是分开的,因为这些内部生成的方法在方法名称中具有特征的名称.当我们在T12中查看实现时: public class T12 extends java.lang.Object implements T1,T2,scala.ScalaObject { private final int Overridden$T1$$v; Signature: I public final int T1$$v(); Signature: ()I Code: 0: aload_0 1: getfield #22; //Field T1$$v:I 4: ireturn public int getValueT1(); Signature: ()I Code: 0: aload_0 1: invokestatic #29; //Method T1$class.getValueT1:(LT1;)I 4: ireturn } 你可以看到它只是填补了每个特定特征所需的内容.现在的问题是 – 特质如何相互覆盖?他们似乎是完全分开的!这是编译器的工作.如果某些东西是私有的,它是隐藏的,不能被覆盖,所以另一个(私有)东西具有相同的名称并不重要.但如果不是,编译器会抱怨碰撞: error: overriding value v in trait T1 of type Int; value v in trait T2 of type Int needs `override' modifier class T12 extends T1 with T2 因为现在它没有使用嵌入了特征名称的秘密错位名称. (观察到此示例中没有损坏getValueT1.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |