Scala - Sifat

Sebuah sifat merangkum metode dan definisi bidang, yang kemudian dapat digunakan kembali dengan mencampurkannya ke dalam kelas. Tidak seperti pewarisan kelas, di mana setiap kelas harus mewarisi hanya dari satu superkelas, kelas dapat mencampurkan sejumlah sifat.

Sifat digunakan untuk menentukan tipe objek dengan menentukan tanda tangan dari metode yang didukung. Scala juga memungkinkan sifat untuk diterapkan sebagian tetapi sifat mungkin tidak memiliki parameter konstruktor.

Definisi sifat terlihat seperti definisi kelas kecuali yang menggunakan kata kunci trait. Berikut ini adalah contoh sintaks dasar dari sifat.

Sintaksis

trait Equal {
   def isEqual(x: Any): Boolean
   def isNotEqual(x: Any): Boolean = !isEqual(x)
}

Sifat ini terdiri dari dua metode isEqual dan isNotEqual. Di sini, kami belum memberikan implementasi apa pun untuk isEqual dimana metode lain menerapkannya. Kelas anak memperluas suatu sifat dapat memberikan implementasi untuk metode yang tidak diimplementasikan. Jadi suatu sifat sangat mirip dengan yang kita milikiabstract classes di Jawa.

Mari kita asumsikan contoh sifat Equal mengandung dua metode isEqual() dan isNotEqual(). SifatnyaEqual berisi satu metode yang diterapkan yaitu isEqual() jadi ketika kelas yang ditentukan pengguna Point memperluas sifat tersebut Equal, implementasi ke isEqual() metode dalam Point kelas harus disediakan.

Di sini perlu diketahui dua metode penting Scala, yang digunakan dalam contoh berikut.

  • obj.isInstanceOf [Point] Untuk memeriksa Jenis objek dan Poin tidak sama.

  • obj.asInstanceOf [Point] Berarti pengecoran tepat dengan mengambil tipe objek dan mengembalikan objek yang sama sebagai tipe Titik.

Coba program contoh berikut untuk mengimplementasikan ciri-ciri.

Contoh

trait Equal {
   def isEqual(x: Any): Boolean
   def isNotEqual(x: Any): Boolean = !isEqual(x)
}

class Point(xc: Int, yc: Int) extends Equal {
   var x: Int = xc
   var y: Int = yc
   
   def isEqual(obj: Any) = obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == y
}

object Demo {
   def main(args: Array[String]) {
      val p1 = new Point(2, 3)
      val p2 = new Point(2, 4)
      val p3 = new Point(3, 3)

      println(p1.isNotEqual(p2))
      println(p1.isNotEqual(p3))
      println(p1.isNotEqual(2))
   }
}

Simpan program di atas dalam Demo.scala. Perintah berikut digunakan untuk mengkompilasi dan menjalankan program ini.

Perintah

\>scalac Demo.scala
\>scala Demo

Keluaran

true
false
true

Kelas nilai dan Sifat Universal

Kelas nilai adalah mekanisme baru di Scala untuk menghindari pengalokasian objek runtime. Ini berisi konstruktor utama dengan tepat satuvalparameter. Ini hanya berisi metode (def) yang tidak diperbolehkan var, val, kelas bersarang, sifat, atau objek. Kelas nilai tidak dapat diperpanjang oleh kelas lain. Ini dapat dimungkinkan dengan memperluas kelas nilai Anda dengan AnyVal. Keamanan jenis tipe data kustom tanpa overhead waktu proses.

Mari kita ambil contoh kelas nilai Weight, Height, Email, Age, dll. Untuk semua contoh ini, tidak perlu mengalokasikan memori dalam aplikasi.

Kelas nilai tidak diperbolehkan untuk memperluas sifat. Untuk mengizinkan kelas nilai memperluas sifat,universal traits diperkenalkan yang meluas untuk Any.

Contoh

trait Printable extends Any {
   def print(): Unit = println(this)
}
class Wrapper(val underlying: Int) extends AnyVal with Printable

object Demo {
   def main(args: Array[String]) {
      val w = new Wrapper(3)
      w.print() // actually requires instantiating a Wrapper instance
   }
}

Simpan program di atas dalam Demo.scala. Perintah berikut digunakan untuk mengkompilasi dan menjalankan program ini.

Perintah

\>scalac Demo.scala
\>scala Demo

Keluaran

Ini akan memberi Anda kode hash dari kelas Wrapper.

Wrapper@13

Kapan Menggunakan Sifat?

Tidak ada aturan tegas, tetapi berikut beberapa pedoman yang perlu dipertimbangkan -

  • Jika perilaku tersebut tidak akan digunakan kembali, maka jadikanlah itu kelas yang konkret. Ini bukan perilaku yang dapat digunakan kembali.

  • Jika dapat digunakan kembali di beberapa kelas yang tidak terkait, jadikan itu ciri. Hanya ciri-ciri yang dapat dicampur ke dalam beberapa bagian hierarki kelas.

  • Jika Anda menghendaki inherit darinya dalam kode Java, gunakan kelas abstrak.

  • Jika Anda berencana untuk mendistribusikannya dalam bentuk terkompilasi, dan Anda mengharapkan grup luar untuk menulis kelas yang mewarisi darinya, Anda mungkin condong ke arah penggunaan kelas abstrak.

  • Jika efisiensi sangat penting, condong ke arah penggunaan kelas.