2014-05-14 35 views
22

abstract override'un tanıtıldığı Scala'da section Programlama'yı okudum, ancak yine de bu değiştiricilerin birleştirilmesiyle tam olarak ne ifade edildiği ile karıştırıldım. kullanılan bu değiştiricileri aşağıda yapıştırılan edildiği kod bloğu: Özellikle"Soyut geçersiz kılma" neden subtraitda "geçersiz kılma" gerektirmiyor?

trait Doubling extends IntQueue { 
    abstract override def put(x: Int) { super.put(2 * x) } 
} 

, ben bu durumda abstract amacıyla karıştı ve neden biz sadece override anahtar kelime ile beklenen sonuçlar elde edilemez. super numaralı telefona bir çağrı eklemediysek, abstract anahtar kelimesine mi ihtiyacımız var? Neden ya da neden olmasın? Bu anahtar sözcüğün, ayrılabilir özelliklerle ilgili birleşik bir açıklaması için ayrıntılı bir açıklama arıyorum.

cevap

18

nedeni temel sınıf yöntemi olmasıdır soyut size aramaktadır açıklama ile sona özelliği üzerinde abstract koymak için olsaydı

abstract class IntQueue { 
    def get(): Int 
    def put(x: Int) 
} 

:

trait Doubling extends IntQueue { 
    override def put(x: Int) { super.put(2 * x) } 
} 
<console>:9: error: method put in class IntQueue is accessed from 
super. It may not be abstract unless it is overridden by a member 
declared `abstract' and `override' 
      override def put(x: Int) { super.put(2 * x) } 

Yani, yöntemi abstract olarak işaretlemeniz gerekir. İşte

denklemin "Diğer taraf" dir: abstract dahil etmek artık gereksizdir

abstract class IntQueue { 
    import collection.mutable._ 
     val q = Queue[Int]() 
     def get(): Int = { q.dequeue() } 
     def put(x: Int) = { q.enqueue(x) } 
    } 

: yöntemleri uygulamaları var yoksa o zaman abstract olarak trait 'ın metodunu işaretlemek için gerekli değildir

trait Doubling extends IntQueue { 
     /* Look Ma! no abstract here ! */ override def put(x: Int) { super.put(2 * x) } 
     } 
defined trait Doubling 
+1

_Thank you_: şimdi çıktı verecektir

class ApprovalDelegate extends ApprovalRequest { override def requestApproval() { println("and now we play the waiting game") } } val adCampaign = new ApprovalDelegate with MarketingApprovalRequest with FinanceApprovalRequest with ExecutiveApprovalRequest 

. Bir sebepten dolayı, istiflenebilir özellik örneklerini 'soyut geçersiz kılma' ile görmeye devam ediyorum, ama bana öyle geliyor ki, iki kavram aslında birbirinden ayrı (her ne kadar her ikisi de dinamik olarak bağlı süper'ye güveniyor olsa da). – Max

5

fikir tamamlanmamış kılma olmasıdır - hala o hypotheti değiştirerek dahi olsa, bu yöntemi sağlamaktır özelliğin sonunda somut uygulanmasını gerektirir istiyorum cal yönteminin davranışı. Başka bir deyişle, geçersiz kıldığınız yöntem tam bağımsız bir uygulama değildir. Python'da method decorator gibi benzer bir etki verir.

Bildiğim kadarıyla ikna edebilir gibi bir özelliğin bir yöntem abstract override ise ve super çağırır, ama buna somut ihtiyacı bilmek yöntemin uygulanmasını incelemek için kod istemci beklemek kapsüllemesini kırar yalnızca uygulanması. Bu nedenle, arayüzü tam olarak tanımlamak için abstract override işaretlemeniz gerekir.

2

late binding in scala traits yazısının bir kısmı; çok net bir açıklama sağlar; verbatim feryat sağlandı (daha fazla bilgi için full post'u okuyun):

Özet temel sınıfı, requestApproval yönteminin bir uygulamasını sağladı. Bu, en soldaki özellik bu yöntemi çağırdığı için iyidir. Temel sınıfın yöntemi soyut ise ne olur?

abstract class ApprovalRequest { 
    def requestApproval() 
} 

bu değiştirirseniz

biz derleyici oldukça garip ileti alıyorum: hatası: yöntem requestApproval sınıfa ApprovalRequest yılında süperden erişilir.o abstract ve override abstract ve override kombinasyonu ilan bir üyesi tarafından yöntemin nihai uygulama sınıfı karıştırma-in özelliği tarafından sağlanacak derleyici söyler geçersiz kılınır sürece soyut olmayabilir. Soyut anahtar kelimeyi yöntemlere eklersek, ApprovalRequest'un anonim uygulanmasını artık kullanamayız. Bu nesne, soyut geçersiz kılma yöntemleri requestApproval'un bir uygulamasının arandığından ve oluşturulmadığından oluşturulamaz. Bunun yerine, ApprovalRequest'u genişleten ve requestApproval'u uygulayan yeni bir sınıf oluşturmamız gerekiyor. Daha sonra özellikleri o sınıfın bir örneğine karıştırıyoruz.

requesting approaval from executives 
requesting approval from Finance 
requesting approval from Marketing 
and now we play the waiting game