Scala’da
trait
ler bulunur vetrait
lerabstract class
tan daha esnektir. Peki öyleyseabstract class
lar neden var? Ne zaman kullanılıyorlar?
Scala’da abstract class’ları kullanmak için iki ana sebep vardır!
- Yapıcı methodlara (
constructors
) ihtiyaç duyanbase class
ları oluşturmak istiyorsak - Kod
Java
kodunda da çağrılacak ise :( :@ :/
Birinci sebeple ilgili olarak, trait
ler constructors
larda parametreye izin vermezler.
// trait buna izin vermiyor
trait Coder(name: String)
Bu nedenle base class
‘ınıza parametre gerekiyorsa abstract class
kullanın.
abstract class Coder(name: String)
İkinci sebebe gelirsek yazdığınız scala
kodu java
tarafından kullanılmak istendiğinde trait
leri java
kodunda çağırdığınızda çalışmadığını göreceksiniz. Şimdilik bunun scala’daki trait
lerden kaynaklandığını bilmeniz yeterlidir. Bunun çözümü olarak abstract class
‘ları kullanıyoruz fakat teknik olarak trait
‘leri implement etmek için farklı çözümlerde bulunmaktadır. Şimdilik bununla ilgili bir işlemimiz olmadığı için detaylı olarak açıklamıyorum.
Önemli Hatırlatmalar
Temel fonksiyonlarda constructor
larınızın parametre alması gerekiyorsa trait
yerine abstract class
kullanın. Bununla birlikte trait
ten farklı olarak bir soyut class
in sadece tek bir class
tarafından miras alınılabileceğini unutmayın.
Abstract Class’lar
Abstract class
lar implementasyonları tamamlayabilmek için tanımladığınız methodları yazmanız ve implementasyonları olmayan diğer methodlar ile birlikte kullanabilmeniz için Java
daki gibi çalışır.
Bir method’u abstract
yapmak istiyorsanız gövdesini boş bırakmanız yeterlidir.
def backend // abstract olması için gövdesini boş bıraktık
Bunun için abstract
anahtar kelimesine ihtiyacımız yoktur. Sadece methodun gövdesini boş bırakmak o class’ı abstract
yapar.
Aşağıdaki örnekte save
, update
ve delete
methodları abstract class BaseController
de tanımlanmıştır fakat connect
, getStatus
, setCollectionName
methodlarının gövdesi boştur ve dolayısıyla bunlar soyuttur.(abstract
tır.)
abstract class BaseController(db: Database) {
def save { db.save }
def update { db.update }
def delete { db.delete }
// abstract
def connect
// geriye string dönen bir abstract method
def getStatus: String
// parametre alan abstract method
def setCollectionName(collectionName: String)
}
Bir class BaseController abstract class
ını miras aldığında connect
, getStatus
ve setCollectionName
methodlarını tanımlamalı yada bunların soyut olduğunu belirtmelidir. Bunu Ammonite Repl
üzerinden denersek Ammonite
bize class need to be abstract
hatasını verecektir.
Welcome to the Ammonite Repl 1.0.3
@> class CoderController(db: Database) extends BaseController(db) <console>:9: error: class CoderController needs to be abstract, since: method setCollectionName in class BaseController of type (serverName: String)Unit is not defined
method getStatus in class BaseController of type => String is not defined method connect in class BaseController of type => Unit is not defined
class CoderController(db: Database) extends BaseController(db)
^
Son olarak; bir abstract class
‘ı sadece bir class miras alabildiği için trait
yada abstract
kullanıp kullanmamaya karar verirken temel uygulamanızda constructor argumanlarına ihtiyaç duymuyorsanız muhakkak trait
kullanın.
Eğer anlamadığınız bir yer var ise alt kısımdaki disqus’a yorum yapabilirsiniz.
İçerikte herhangi bir eksiklik veyahut yanlış olduğunu düşündüğünüz bir kısım var ise mail atmaktan çekinmeyin.