Bu, yalnızca A with B
'un yeni bir tür olarak görülmesi gerektiğinden değil. Scala tipi sistemde, A with B
'a karşılık gelen bir sınıf varsa doğrudan sorun olmaz. o köprüyü de karışmış durumda özelliklerin tüm yöntemler için yöntemleri içermesi gerekir, çünkü Anonim sınıf oluşturulur.
oluşturulur anonim sınıf nesnesi tüm yöntemlerin uygulamaları olması gerektiğini olmasının sebebi A
ve B
'dan tüm yöntemler. JVM bayt kodu düzeyinde, bu, birden fazla sınıfın miras alınıp alınmayacağını ve birden fazla kalıtım modelinin JVM'de desteklenmeyeceğini belirtir. özellik T
hiçbir yöntem uygulamaları varsa
- bir oluşturur: Bir özelliği oluşturduğunuzda Scala şunları yapar (ancak bunu aramak istediğiniz veya mixin kompozisyon) çoklu mirası simüle etmek Özellikdeki tüm yöntemleri tanımlayan arayüz.
T
özelliğinin, yöntem uygulamalarına sahip olması durumunda, numaralı belgede somut yöntemlerin her biri için statik bir yöntemi olan bir T$class
sınıfı oluşturur. Bu statik yöntem, T
'daki karşılık gelen yöntemle aynı gövdeye sahiptir, ancak imzası, this
parametresini içerecek şekilde değiştirilmiştir.T
varsa:
def foo(x: Int) = x
sonra
T$class
sahip olacaktır:
<static> def foo($this: T, x: Int) = x
bir sınıf A
ve bazı özellik T
arasında mixin bileşimi ile elde edilen sınıfı, daha sonra özel bir köprü yöntemi ileten oluşturulan olacaktır Gövde içeren statik yönteme çağrı. Bu şekilde, yöntemin gövdesi, T
'da karışan her sınıfta çoğaltılamaz. Bu nedenle, anonim sınıfın oluşturulması gerekir - T
'da her yöntem için tanımlanan köprü yöntemlerine sahip olması gerekir.
İşte bir örnek. Mixin kompozisyonu yaparak yeni bir sınıf oluşturduğunuzda, ör. new A with T
çağırır: derleyici aslında doğrusu callsite doğrudan statik yöntemleri çağırmak için foo
için callsites yeniden verebilecek
class A {
def bar = println("!")
}
<interface> T {
def foo(x: Int): Int
}
class T$class {
<static> def foo($this: T, x: Int) = x
}
class $anon extends A <implements> T {
// notice that `bar` is inherited, but `foo` is not
<bridge> def foo(x: Int) = T$class.foo(this, x)
}
new $anon
Uyarı:
class A {
def bar = println("!")
}
trait T {
def foo(x: Int) = x
}
new A with T
derleyici kabaca böyle bir şey için yeniden yazmak olacaktır bir köprü yönteminden daha. Bu şekilde yapılmamasının nedeni, o zaman artık alt-polimorfizmi desteklemeyeceği içindir.
+1 özellikle bir örnek göstermek için! –
Harika cevap, çok teşekkür ederim. –
'-Xprint: mixin' argümanı ile' scalac'ı çağırmanın Scala'nın yarattığı kesin yapıyı göstereceğini unutmayın. -Xshow-phase-'-Xprint:' ile kullanılabilecek diğer aşamaları gösterir. – outis