gpt4 book ai didi

Scala:将特征与私有(private)字段混合

转载 作者:行者123 更新时间:2023-12-04 09:28:33 25 4
gpt4 key购买 nike

这不是什么大问题,而是我的兴奋,这完全有可能!我写这个小例子只是为了证明相反的情况——我期望编译器错误或其中一个值(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 不被覆盖?当然,这仅适用于 v s 是私有(private)的,但仍然。

最佳答案

由于特征不仅仅是接口(interface),它们需要某种方式来存储它们的内部状态。但是它们必须与接口(interface)兼容——那么它们是做什么的呢?他们为看起来像一个字段的内容创建访问器(正如您在类文件中使用 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
}

您可以看到它只是填充了每个特定特征所需的内容。现在的问题是——特征如何相互覆盖?他们似乎完全分开了!那是编译器的工作。如果某事是 private它是隐藏的并且不能被覆盖,所以另一个(私有(private))事物具有相同的名称并不重要。但如果不是,编译器会提示冲突:
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

因为现在它没有使用嵌入特征名称的 secret 重整名称。 (注意 getValueT1 在这个例子中没有被破坏。)

关于Scala:将特征与私有(private)字段混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5203798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com