2016-11-13 31 views
7

Ben ifadenin lineerizasyon BScala istiflenebilir özellikleri kodu için

olan E ile C D

yeni E anlama aşağıdaki gibi Aşağıda,

kodundaki d.foo(), CBDE yerine ECBD'ye değerlendirilmiştir. Neyi kaçırıyorum?

trait A { 
     def foo(): String = "" 
    } 

    trait B extends A { 
     abstract override def foo() = "B" + super.foo() 
    } 

    trait C extends B { 
     abstract override def foo() = "C" + super.foo() 
    } 

    trait D extends A { 
     abstract override def foo() = "D" + super.foo() 
    } 

    class E extends A{ 
     override def foo() = "E" 
    } 

    var d = new E with D with C with B; 
    d.foo() //prints CBDE 

ben aşağıda

class F extends A with D with C with B{ 
     override def foo() = "F" + super.foo() 
} 

gibi bir sınıf F varsa ve eğer

new F().foo 

o O biraz tutarsız görünüyor

"FCBD" yazdırır fark etmiş çünkü sınıf F ifadesiyle aynı şekilde karıştırılıyor ama farklı bir baskı siparişi var

cevap

4

new E with D with C with B ile ilk durum mükemmel şekilde açıklanmıştır here. Onun lineerizasyon EDBC, yani , bu

  • ilk görüşmeleri ardından B#foo()
  • , çağırdığınızda
  • sonra D#foo()
  • ve son olarak E#foo().

Eğer E bir özellik yapmak ve sonunda onu karıştırırsanız: özellik E Lineerleştirmede "son" ve sadece foo kıldığından val d = new D with C with B with E ardından , sadece "E" dönecektir. Eğer "F" + super.foo() olarak foo tanımlamak için

F durumunda, farklıdır ve bu durumda super olan doğrusallaştırma ADBC olan A with D with C with B, yani new F().foo() - önce baskılar "F", - sonra onun super.foo()"CBD" olup.

arada, o zaman o E yılında A takımından foo böylece "A" sonucu görünmüyor geçersiz göreceksiniz "A" dönmek için A#foo() değiştirmeyi deneyin ve F o "FCBDA" olduğunu.