Article Image
Article Image
read

Scala’da traitler bulunur ve traitler abstract classtan daha esnektir. Peki öyleyse abstract classlar neden var? Ne zaman kullanılıyorlar?

Scala’da abstract class’ları kullanmak için iki ana sebep vardır!

  1. Yapıcı methodlara (constructors) ihtiyaç duyan base classları oluşturmak istiyorsak
  2. Kod Java kodunda da çağrılacak ise :( :@ :/

Birinci sebeple ilgili olarak, traitler constructorslarda 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 traitleri java kodunda çağırdığınızda çalışmadığını göreceksiniz. Şimdilik bunun scala’daki traitlerden 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 constructorlarınızın parametre alması gerekiyorsa trait yerine abstract class kullanın. Bununla birlikte traitten farklı olarak bir soyut classin sadece tek bir class tarafından miras alınılabileceğini unutmayın.

Abstract Class’lar

Abstract classlar implementasyonları tamamlayabilmek için tanımladığınız methodları yazmanız ve implementasyonları olmayan diğer methodlar ile birlikte kullanabilmeniz için Javadaki 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 BaseControllerde tanımlanmıştır fakat connect, getStatus, setCollectionName methodlarının gövdesi boştur ve dolayısıyla bunlar soyuttur.(abstracttı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.

Blog Logo

Abdullah Velioglu


Published

Image

A Snowball Effect

A Personal Blog For Abdullah

Back to Overview