当类具有方法实现时,为什么要调用traits方法

时间:2017-10-05 08:11:03

标签: scala

在以下代码中,为什么即使B类已定义A1,也会调用特征CD的方法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抽象强文

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来实现打印B?

阶> 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

2 个答案:

答案 0 :(得分:0)

我想我正在使用的是可堆叠的特征模式。基本上,如果我使用super并调用方法,编译器将查看该方法是在D中定义,然后是C,然后是B(顺序是从右到左)。当编译器看到它使用它的实现时。使用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(最右边,顺序是从右到左)并找到A1并使用那个实现。由于D不再使用超级,Bscala> 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。这会改变订单或打印。

A1

当调用A1时,在从D调用scala> val b3 = new B with D with C b3: B with D with C = $anon$1@7b3c0ecb scala> b3.A1 C D scala> 之后,编译器会查找超类的filter50WithTagSkip(tag, skip) { return new Promise((resolve, reject) => { const regex = new RegExp(tag, 'g'); const or_criteria = [ // { firstName: { $regex: regex, $options: 'i' } }, // { lastName: { $regex: regex, $options: 'i' } }, { fullName: { $regex: regex, $options: 'i' } }, { email: { $regex: regex, $options: 'i' } }, { phone: { $regex: regex, $options: 'i' } } ]; const project_criteria = { deleted: 1, // firstName: 1, // lastName: 1, email: 1, phone: 1, fullName: { $concat: ['$firstName', ' ', '$lastName'] } }; const match_criteria = { $or: or_criteria, deleted: false }; const aggregate_criteria = [{ $project: project_criteria }, { $match: match_criteria }]; this._db.collection(this._table) .aggregate(aggregate_criteria) .skip(skip) .limit(50) .toArray((err, res) => { if (err) { this._logger.error(err); reject(err); } else { resolve(res); } }); }); } (左边的下一个)并继续向左移动。

{{1}}

答案 1 :(得分:0)

  

为什么在我调用B的A1时打印C和D.不应该B的A1只调用B的A2来实现打印B?

没有。 super.A1是指A#A1,它会调用被调用对象的A2:不是B#A2,不是A#A2,而是this.A2

此外,CDB无关,因此在任何情况下他们都无法调用B#A1:您的意思是{ {1}}?