Apa alasan di balik memiliki objek pendamping di Scala?

Jawaban:

82

Objek pendamping pada dasarnya menyediakan tempat di mana seseorang dapat meletakkan metode "seperti statis". Selanjutnya, objek pendamping, atau modul pendamping, memiliki akses penuh ke anggota kelas, termasuk yang pribadi.

Objek pendamping sangat bagus untuk merangkum hal-hal seperti metode pabrik. Daripada harus memiliki, misalnya, Foodan di FooFactorymana saja, Anda dapat meminta kelas dengan objek pendamping untuk mengambil tanggung jawab pabrik.

Saem
sumber
61

Objek pendamping berguna untuk menyimpan status dan metode yang umum untuk semua instance kelas, tetapi tidak menggunakan metode atau kolom statis . Mereka menggunakan metode virtual biasa yang dapat diganti melalui pewarisan. Scala benar-benar tidak statis. Ada banyak cara untuk menggunakan ini, tetapi berikut adalah contoh sederhananya.

abstract class AnimalCounter
{
    var animals = 0

    def name: String

    def count()
    {
        animals += 1
        println("%d %ss created so far".format(animals, name))
    }
}

abstract class Animal
{
    def companion: AnimalCounter
    companion.count()
}

object Dog extends AnimalCounter
{
    val name = "dog"
}

class Dog extends Animal
{
    def companion = Dog
}

object Cat extends AnimalCounter
{
    val name = "cat"
}

class Cat extends Animal
{
    def companion = Cat
}

Yang menghasilkan keluaran ini:

scala> new Dog
1 dogs created so far

scala> new Cat
1 cats created so far

scala> new Dog
2 dogs created so far

scala> new Cat
2 cats created so far
Craig P. Motlin
sumber
1
ilustrasi serupa dapat ditemukan juga di sini: daily-scala.blogspot.sk/2009/09/companion-object.html
xhudik
30

... dan ini adalah tempat yang baik untuk menyimpan metode pabrik statis (bukan DP) untuk kelas yang menyertai. Jika Anda menamai metode pabrik yang kelebihan beban tersebut berlaku (/ ... /) Anda akan dapat membuat / menginisialisasi kelas Anda

  1. tanpa 'baru' (tidak terlalu penting)

  2. dengan kemungkinan set parameter yang berbeda (bandingkan dengan apa yang ditulis Bloch di Java Efektif tentang konstruktor telescoping)

  3. dengan kemampuan untuk memutuskan kelas turunan mana yang ingin Anda buat, bukan yang abstrak (disertai)

Kode contoh:

abstract class AbstractClass;
class RealThing(s: String) extends AbstractClass;
class AlternativeThing(i: Int) extends AbstractClass;
object AbstractClass {
  def apply(s: String) = {
    new RealThing(s)
  }
  def apply(i: Int) = {
    new AlternativeThing(i)
  }
}

// somewhere else you can
val vs = AbstractClass("asdf")  // gives you the RealThing wrapped over string
val vi = AbstractClass(123)  // gives you AlternativeThing wrapped over int

Saya tidak akan memanggil objek / kelas dasar AbstractXxxxx karena tidak terlihat buruk: seperti membuat sesuatu yang abstrak. Beri nama-nama itu arti yang sebenarnya. Pertimbangkan untuk menggunakan kelas kasus yang tidak dapat diubah, metode kurang, dan segel kelas dasar abstrak.

Szymon Jachim
sumber
2
RealThingdan AlternativeThingkelas harus memiliki privatekonstruktor untuk memaksa pengguna menggunakan AbstractClasspabrik has. class AlternativeThing private(i: Int) extends AbstractClass
metch
@ [Szymon Jachim] Kelas abstrak Scala tidak mendukung pewarisan ganda. Jadi mengapa kompiler mengizinkannya dalam kasus Anda?
user2441441
19

Selain hal-hal yang dikatakan Saem dalam balasannya , pengompilasi Scala juga mencari jenis konversi implisit dalam objek pendamping yang sesuai (baik dari sumber atau target), sehingga konversi tidak perlu diimpor.

Tentang alasan objek tunggal dalam Pemrograman umum di Scala mengatakan:

Seperti disebutkan di Bab 1, salah satu cara di mana Scala lebih berorientasi objek daripada Java adalah kelas di Scala tidak dapat memiliki anggota statis. Sebaliknya, Scala memiliki objek tunggal (p. 65).

Fabian Steeg
sumber
3

Saya selalu melihat objek pendamping sebagai jembatan untuk menulis kode fungsional dan berorientasi objek di Scala. Seringkali kita hanya membutuhkan fungsi murni yang mengambil beberapa masukan dan memberikan hasil pemrosesan. Menempatkan fungsi-fungsi yang relevan di objek pendamping membuatnya mudah untuk dicari dan digunakan, untuk saya sendiri dan juga seseorang yang membangun di atas kode saya.

Selain itu, ini adalah fitur yang disediakan bahasa untuk menulis pola tunggal tanpa melakukan apa pun. Ini sangat berguna ketika Anda membutuhkan singleton untuk merangkum delegator untuk masa pakai JVM. Misalnya, menulis pustaka klien HTTP sederhana di Scala tempat Anda dapat merangkum delegator berbasis implementasi Java yang mendasari dan membiarkan konsumen API Anda hidup di dunia murni.

Gaurav Abbi
sumber
0

Jika Anda mendefinisikan kelas dan objek dalam file yang sama dengan nama yang sama, mereka dikenal sebagai kelas dan objek pendamping. Scala tidak memiliki statis sebagai kata kunci JAVA, Anda dapat mengambil statis sebagai pengganti kelas dan objek pendamping di Scala.

Untuk informasi lebih detail silakan cek kelas artikel dan kata kunci objek dalam pemrograman scala

FOD
sumber
-1

Pada awalnya, ini memberikan pemisahan yang jelas antara metode metode statis vs non statis, juga menyediakan cara sederhana untuk membuat kelas tunggal.

Ia juga dapat mewarisi metode dari kelas dan / atau sifat lain, yang tidak dapat dilakukan dengan metode statis Java. Dan dapat dikirimkan sebagai parameter.

vipin
sumber