Scala 当一个类有method';实施
在下面的代码中,为什么即使B类定义了Scala 当一个类有method';实施,scala,Scala,在下面的代码中,为什么即使B类定义了A1,也调用了traitsC和D的方法A1 scala> trait A { | def A1 = A2 | def A2 //A2 is abstract and need implementation | } defined trait A scala> class B extends A { | def A2 = println("B") //implemented A2 in B | }
A1
,也调用了traitsC
和D
的方法A1
scala> trait A {
| def A1 = A2
| def A2 //A2 is abstract and need implementation
| }
defined trait A
scala> class B extends A {
| def A2 = println("B") //implemented A2 in B
| }
defined class B
scala> val b1 = new B
b1: B = B@163e8949
这个很好用
scala> b1.A1
B
scala> b1.A2
B
现在我混合了各种特征。C仍然有A2摘要
scala> trait C extends A {
| abstract override def A1 = {super.A1; C}
| def C = println("C")
| }
defined trait C
D仍然有A2摘要strong文本
scala> trait D extends A {
| abstract override def A1 = {super.A1; D}
| def D = println("D")
| }
defined trait D
为什么当我调用B的A1时C和D被打印。B的A1不应该只调用B的A2吗?A2被实现为打印B
scala>val b2=新的B带C带D
b2: B with C with D = $anon$1@701d2b59
scala> b2.A1
B
C
D
scala> b2.A2
B
scala> val b3 = new B with D with C
b3: B with D with C = $anon$1@270f28cf
scala> b3.A1
B
D
C
我想我正在使用的是所谓的堆叠特征模式。基本上,如果我使用
new B和C with D
并调用一个方法,编译器将看到该方法是在D中定义的,然后是C,然后是B(顺序是从右到左)。当编译器看到一个实现时,它会使用它。使用super
可以使编译器调用类或左侧trait中的下一个实现(同样是从右到左的顺序)
已删除super
调用
scala> trait D extends A {
| abstract override def A1 = { D}
| def D = println("D")
| }
defined trait D
scala> trait C extends A {
| abstract override def A1 = { C }
| def C = println("C")
| }
defined trait C
scala> val b3 = new B with D with C
b3: B with D with C = $anon$1@7417ef4f
当super
被删除时,当编译器看到对A1
的调用时,它首先检查C
(最右边,顺序是从右到左),然后找到A1
,并使用该实现。由于A1
不再使用super,因此D
或B
中的A1
不会被调用
scala> b3.A1
C
如果D
是最右边的,则只调用D
的A1
scala> val b3 = new B with C with D
b3: B with C with D = $anon$1@fd4459b
scala> b3.A1
D
打印后添加了super
。这会改变订单或打印
scala> trait C extends A {
| abstract override def A1 = { C ; super.A1}
| def C = println("C")
| }
defined trait C
scala> val b3 = new B with C with D
b3: B with C with D = $anon$1@4489f60f
scala> b3.A1
D
当调用super
时,在从D调用A1
之后,编译器查找超类的A1
(左边的下一个)并继续向左移动
scala> val b3 = new B with D with C
b3: B with D with C = $anon$1@7b3c0ecb
scala> b3.A1
C
D
scala>
我想我正在使用的是所谓的堆叠特征模式。基本上,如果我使用
new B和C with D
并调用一个方法,编译器将看到该方法是在D中定义的,然后是C,然后是B(顺序是从右到左)。当编译器看到一个实现时,它会使用它。使用super
可以使编译器调用类或左侧trait中的下一个实现(同样是从右到左的顺序)
已删除super
调用
scala> trait D extends A {
| abstract override def A1 = { D}
| def D = println("D")
| }
defined trait D
scala> trait C extends A {
| abstract override def A1 = { C }
| def C = println("C")
| }
defined trait C
scala> val b3 = new B with D with C
b3: B with D with C = $anon$1@7417ef4f
当super
被删除时,当编译器看到对A1
的调用时,它首先检查C
(最右边,顺序是从右到左),然后找到A1
,并使用该实现。由于A1
不再使用super,因此D
或B
中的A1
不会被调用
scala> b3.A1
C
如果D
是最右边的,则只调用D
的A1
scala> val b3 = new B with C with D
b3: B with C with D = $anon$1@fd4459b
scala> b3.A1
D
打印后添加了super
。这会改变订单或打印
scala> trait C extends A {
| abstract override def A1 = { C ; super.A1}
| def C = println("C")
| }
defined trait C
scala> val b3 = new B with C with D
b3: B with C with D = $anon$1@4489f60f
scala> b3.A1
D
当调用super
时,在从D调用A1
之后,编译器查找超类的A1
(左边的下一个)并继续向左移动
scala> val b3 = new B with D with C
b3: B with D with C = $anon$1@7b3c0ecb
scala> b3.A1
C
D
scala>
为什么当我调用B的A1时C和D被打印。B的A1不应该只调用B的A2吗?A2被实现为打印B
否。super.A1
指的是A#A1
,它调用它所调用的对象的A2
:不是B#A2
,不是A#A2
,而是this.A2
而且,C
和D
与B
没有任何关系,所以他们无论如何都不能调用B#A1
:你是说C/D类扩展了B
为什么当我调用B的A1时C和D被打印。B的A1不应该只调用B的A2吗?A2被实现为打印B
否。super.A1
指的是A#A1
,它调用它所调用的对象的A2
:不是B#A2
,不是A#A2
,而是this.A2
而且,
C
和D
与B
没有任何关系,所以他们无论如何都不能调用B\A1
:你是说类C/D扩展了B
?你想实现什么?还要看看Scala是如何工作的。示例非常有效。我想了解特征是如何被称为的。我想我现在得到了一个提示,def
在trait中没有类型,def
w/同名(仍然没有类型)没有override
你想要实现什么?还要看看Scala是如何工作的。示例非常有效。我想了解特征是如何被称为的。我想我现在得到了一个提示,def
在trait中没有类型,def
w/同名(仍然没有类型)没有override