Soyut sınıflar yerine özellikleri kullanmanın avantajları nelerdir?


81

Birisi lütfen Scala'daki özellikleri açıklayabilir mi? Soyut bir sınıfı genişletmeye kıyasla özelliklerin avantajları nelerdir?

Yanıtlar:


80

Kısa cevap, birden çok özelliği kullanabileceğinizdir - bunlar "istiflenebilir" dir. Ayrıca, özelliklerin yapıcı parametreleri olamaz.

İşte özelliklerin nasıl istiflendiği. Özelliklerin sıralanmasının önemli olduğuna dikkat edin. Birbirlerini sağdan sola arayacaklar.

class Ball {
  def properties(): List[String] = List()
  override def toString() = "It's a" +
    properties.mkString(" ", ", ", " ") +
    "ball"
}

trait Red extends Ball {
  override def properties() = super.properties ::: List("red")
}

trait Shiny extends Ball {
  override def properties() = super.properties ::: List("shiny")
}

object Balls {
  def main(args: Array[String]) {
    val myBall = new Ball with Shiny with Red
    println(myBall) // It's a shiny, red ball
  }
}

4
Yapıcı parametrelerinin eksikliği, neredeyse özelliklerde tür parametreleri kullanılarak oluşturulur.
Jus12

19

Bu site , özellik kullanımına iyi bir örnek verir. Özelliklerin büyük bir avantajı, birden fazla özelliği genişletebilmeniz, ancak yalnızca bir soyut sınıf olmasıdır. Özellikler çoklu kalıtımla birçok sorunu çözer ancak kodun yeniden kullanımına izin verir.

Ruby'yi biliyorsanız, özellikler karışıklara benzer


5
package ground.learning.scala.traits

/**
 * Created by Mohan on 31/08/2014.
 *
 * Stacks are layered one top of another, when moving from Left -> Right,
 * Right most will be at the top layer, and receives method call.
 */
object TraitMain {

  def main(args: Array[String]) {
    val strangers: List[NoEmotion] = List(
      new Stranger("Ray") with NoEmotion,
      new Stranger("Ray") with Bad,
      new Stranger("Ray") with Good,
      new Stranger("Ray") with Good with Bad,
      new Stranger("Ray") with Bad with Good)
    println(strangers.map(_.hi + "\n"))
  }
}

trait NoEmotion {
  def value: String

  def hi = "I am " + value
}

trait Good extends NoEmotion {
  override def hi = "I am " + value + ", It is a beautiful day!"
}

trait Bad extends NoEmotion {
  override def hi = "I am " + value + ", It is a bad day!"
}

case class Stranger(value: String) {
}
Çıktı :

Liste (Ben Ray'im
Ben Ray, kötü bir gün!
Ben Ray, Güzel bir gün!
Ben Ray, kötü bir gün!
Ben Ray, Güzel bir gün!
)



3

Özellikler, işlevselliği bir sınıfa karıştırmak için yararlıdır. Http://scalatest.org/ adresine bir göz atın . Etki alanına özgü çeşitli dilleri (DSL) bir test sınıfına nasıl karıştırabileceğinizi not edin. Scalatest tarafından desteklenen bazı DSL'lere bakmak için hızlı başlangıç ​​kılavuzuna bakın ( http://scalatest.org/quick_start )


1

Java'daki arayüzlere benzer şekilde, özellikler, desteklenen yöntemlerin imzasını belirterek nesne türlerini tanımlamak için kullanılır.

Java'dan farklı olarak Scala, özelliklerin kısmen uygulanmasına izin verir; yani, bazı yöntemler için varsayılan uygulamaları tanımlamak mümkündür.

Sınıfların aksine, özelliklerin yapıcı parametreleri olmayabilir. Özellikler sınıflar gibidir, ancak sınıfların somut değerler ve uygulamalar sağlayabileceği bir işlev ve alan arabirimi tanımlayan özelliklerdir.

Özellikler diğer özelliklerden veya sınıflardan miras alabilir.


1

Scala, First Edition'da Programming kitabının web sitesinden ve daha spesifik olarak Bölüm 12'den " Özelleştirmek mi yoksa değil mi? " Adlı bölümden alıntı yapıyorum .

Yeniden kullanılabilir bir davranış koleksiyonunu uyguladığınızda, bir özellik mi yoksa soyut bir sınıf mı kullanmak istediğinize karar vermeniz gerekecektir. Kesin bir kural yoktur, ancak bu bölüm dikkate alınması gereken birkaç yönerge içermektedir.

Davranış yeniden kullanılmayacaksa, onu somut bir sınıf haline getirin. Ne de olsa yeniden kullanılabilir bir davranış değil.

Birden çok, ilgisiz sınıfta yeniden kullanılabilecekse, onu bir özellik haline getirin. Yalnızca özellikler, sınıf hiyerarşisinin farklı bölümlerine karıştırılabilir.

Yukarıdaki bağlantıda özelliklerle ilgili biraz daha bilgi var ve tam bölümü okumanızı öneririm. Umarım bu yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.