加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读