Perbedaan antara objek dan kelas di Scala

636

Saya hanya akan membahas beberapa tutorial Scala di Internet dan telah memperhatikan dalam beberapa contoh objek dinyatakan pada awal contoh.

Apa perbedaan antara classdan objectdalam Scala?

Steve
sumber

Jawaban:

580

tl; dr

  • class C mendefinisikan sebuah kelas, seperti halnya di Java atau C ++.
  • object Omenciptakan objek tunggalO sebagai turunan dari beberapa kelas anonim; dapat digunakan untuk menampung anggota statis yang tidak terkait dengan instance beberapa kelas.
  • object O extends Tmenjadikan objek Osebagai instance dari trait T; Anda kemudian bisa lewat di Omana saja, yang Tdiharapkan.
  • jika ada class C, maka object Cadalah objek pendamping kelas C; perhatikan bahwa objek pendamping tidak secara otomatis turunan dari C.

Lihat juga dokumentasi Scala untuk objek dan kelas .

object sebagai tuan rumah anggota statis

Paling sering, Anda memerlukan sebuah objectuntuk menyimpan metode dan nilai / variabel yang harus tersedia tanpa harus terlebih dahulu membuat instance instance dari beberapa kelas. Penggunaan ini terkait erat dengan staticanggota di Jawa.

object A {
  def twice(i: Int): Int = 2*i
}

Anda kemudian dapat memanggil metode di atas menggunakan A.twice(2).

Jika twiceadalah anggota dari beberapa kelas A, maka Anda harus membuat instance terlebih dahulu:

class A() {
  def twice(i: Int): Int = 2 * i
}

val a = new A()
a.twice(2)

Anda dapat melihat betapa mubazirnya ini, karena twicetidak memerlukan data spesifik-instance.

object sebagai contoh bernama khusus

Anda juga dapat menggunakan objectitu sendiri sebagai beberapa contoh khusus dari kelas atau sifat. Ketika Anda melakukan ini, objek Anda perlu memperluas beberapa traituntuk menjadi turunan dari subkelasnya.

Pertimbangkan kode berikut:

object A extends B with C {
  ...
}

Deklarasi ini pertama-tama mendeklarasikan kelas anonim (tidak dapat diakses) yang memperluas keduanya Bdan C, dan membuat instance turunan dari kelas ini bernama A.

Ini berarti Adapat diteruskan ke fungsi mengharapkan objek bertipe Batau C, atau B with C.

Fitur Tambahan object

Ada juga ada beberapa fitur khusus objek di Scala. Saya merekomendasikan untuk membaca dokumentasi resmi .

  • def apply(...) mengaktifkan sintaks tanpa nama metode biasa A(...)
  • def unapply(...)memungkinkan untuk membuat ekstraktor pencocokan pola khusus
  • jika menyertai kelas dengan nama yang sama, objek mengasumsikan peran khusus ketika menyelesaikan parameter implisit
ziggystar
sumber
38
Ini juga akan mendefinisikan kelas A, dan membuat semua metode dalam objek A sebagai metode statis pada kelas A (untuk berinteraksi dengan Java). (Modulo bug di Scala 2.7 yang sudah diperbaiki di Scala 2.8)
Ken Bloom
2
@ KenBloom benar-benar? Saya mencoba dan tidak berhasil: scala> Commerce res8: Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <console>: 23: error: tidak ditemukan: ketik Commerce classOf [Commerce] ^ scala> Commerce baru < konsol>: 23: kesalahan: tidak ditemukan: ketik Commerce perdagangan baru ^
Hendy Irawan
3
@Hendy: Scala tidak akan mengenali Commercekelas, tetapi JVM dan bahasa Java akan melakukannya. (Begitulah cara Anda dapat melakukan object Foo{ def main(args:Seq[String]) }dan mengharapkan program berjalan.)
Ken Bloom
3
Saya pikir jawaban ziggystar lebih tepat, kelasnya adalah kelas anonim, kecuali kelas yang sesuai bernama Commerce secara eksplisit didefinisikan (maka objek Commerce akan menjadi objek pendamping untuk kelas Commerce)
Hendy Irawan
3
@ Davidvidplauer saya bertaruh ada cukup banyak kehalusan yang tidak tercakup oleh jawaban saya. Tapi itu mungkin tidak masalah bagi kebanyakan orang yang membaca ini. Dan saya tidak pernah bermasalah dengan melewatkan objek sebagai contoh dari beberapa sifat, yang tidak berarti mereka tidak ada; tetapi harus bekerja.
ziggystar
249

A classadalah definisi, deskripsi. Ini mendefinisikan jenis dalam hal metode dan komposisi jenis lainnya.

An objectadalah singleton - turunan dari sebuah kelas yang dijamin unik. Untuk setiap objectkode, kelas anonim dibuat, yang mewarisi dari kelas apa pun yang Anda nyatakan objectakan diterapkan. Kelas ini tidak dapat dilihat dari kode sumber Scala - meskipun Anda bisa mendapatkannya melalui refleksi.

Ada hubungan antara objectdan class. Suatu objek dikatakan sebagai objek pendamping kelas jika mereka memiliki nama yang sama. Ketika ini terjadi, masing-masing memiliki akses ke metode privatevisibilitas yang lain. Metode ini tidak diimpor secara otomatis. Anda harus mengimpornya secara eksplisit, atau awalan dengan nama kelas / objek.

Sebagai contoh:

class X {
  // class X can see private members of object X
  // Prefix to call
  def m(x: Int) = X.f(x)

  // Import and use
  import X._
  def n(x: Int) = f(x)

  private def o = 2
}

object X {
  private def f(x: Int) = x * x

  // object X can see private members of class X
  def g(x: X) = {
    import x._
    x.o * o // fully specified and imported
   }
}
Daniel C. Sobral
sumber
1
Maaf mengganggu Anda, tetapi bisakah Anda mengarahkan ke contoh tentang cara mengimpor metode ke objek pengiring atau cara mengawalinya?
ithkuil
4
@ithkuil Selesai. Maaf tentang contoh konyol, saya tidak bisa memikirkan yang baik dan pendek.
Daniel C. Sobral
Bagaimana jika saya ingin menggunakan metode kelas di Object? Apakah itu mungkin? Jika saya memiliki metode kelas dan saya ingin menggunakannya di Object, maka jika Anda mencoba mengimpor kelas, Anda tidak akan bisa melakukannya. Akhirnya Anda harus membuat konstruktor dan memanggil metode itu. Jadi, dengan membuat objek pendamping, Anda dapat mengakses metode Obyek menggunakan impor tetapi tidak sebaliknya. Bisakah seseorang memvalidasi?
piyushGoyal
@piyushGoyal Tidak benar. Katakanlah objek memiliki metode def f(x: X) = ???, maka itu akan dapat memanggil metode pribadi x, dari kelas pendamping X.
Daniel C. Sobral
Di sini X lulus dalam fungsi adalah instance dari kelas XI tebak? Jika ya, maka pada akhirnya Anda menggunakan objek x untuk memanggil metode kelas X di def f .. Benar?
piyushGoyal
76

Objek memiliki tepat satu instance (Anda tidak dapat memanggil new MyObject). Anda dapat memiliki beberapa instance kelas.

Obyek melayani sama (dan beberapa tambahan) tujuan sebagai metode statis dan bidang di Jawa.

Thomas Jung
sumber
19

Seperti yang telah dijelaskan oleh banyak orang, objectmendefinisikan contoh tunggal. Satu hal dalam jawaban di sini yang saya yakini ditinggalkan adalah objectmelayani beberapa tujuan.

  • Ini bisa menjadi objek pendamping ke class/ trait, yang mengandung apa yang mungkin dianggap metode statis atau metode kenyamanan.

  • Ia dapat bertindak seperti sebuah modul, berisi tipe dan definisi terkait / tambahan, dll.

  • Itu dapat mengimplementasikan antarmuka dengan memperluas classsatu atau lebih traits.

  • Itu bisa mewakili kasus dari sealed traityang tidak mengandung data. Dalam hal ini, sering dianggap lebih benar daripada case classtanpa parameter. Kasus khusus sealed traitdengan case objectimplementor hanya kurang lebih adalah versi Scala dari enum.

  • Itu dapat bertindak sebagai bukti untuk implicitlogika-driven.

  • Ini memperkenalkan tipe singleton.

Ini adalah konstruksi yang sangat kuat dan umum. Apa yang bisa sangat membingungkan bagi pemula Scala adalah bahwa konstruksi yang sama dapat memiliki kegunaan yang sangat berbeda. Dan objectdapat melayani banyak kegunaan yang berbeda sekaligus, yang bahkan bisa lebih membingungkan.

acjay
sumber
18

Mendefinisikan objek di Scala seperti mendefinisikan kelas di Java yang hanya memiliki metode statis. Namun, dalam Scala suatu objek dapat memperluas superclass lain, mengimplementasikan antarmuka, dan diteruskan seolah-olah itu adalah instance dari sebuah kelas. (Jadi seperti metode statis di kelas tapi lebih baik).

Ken Bloom
sumber
17

Perbedaan formal -

  1. Anda tidak dapat memberikan parameter konstruktor untuk Objek
  2. Objek bukan tipe - Anda tidak boleh membuat instance dengan operator baru. Tetapi dapat memiliki bidang, metode, memperpanjang superclass dan mencampurkan sifat.

Perbedaan penggunaan:

  • Scala tidak memiliki metode atau bidang statis. Sebaliknya Anda harus menggunakan object. Anda dapat menggunakannya dengan atau tanpa kelas terkait. Dalam 1 kasus itu disebut objek pengiring. Kamu harus:
    1. gunakan nama yang sama untuk kelas dan objek
    2. letakkan di file sumber yang sama.
  • Untuk membuat program, Anda harus menggunakan metode utama object, bukan di class.

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
  • Anda juga dapat menggunakannya saat menggunakan objek singleton di java.

      
        
      

irudyak
sumber
"Anda tidak dapat memberikan parameter konstruktor untuk Objek" Objek memiliki metode apply (...), yang fungsinya sangat mirip dengan konstruktor. Ini membuat saya sedikit bingung.
Danielle
7

Kata kunci objek membuat tipe singleton baru, yang seperti kelas yang hanya memiliki instance bernama tunggal. Jika Anda terbiasa dengan Java, mendeklarasikan objek dalam Scala sangat mirip dengan membuat instance baru dari kelas anonim.

Scala tidak memiliki padanan dengan kata kunci statis Java , dan sebuah objek sering digunakan dalam Scala di mana Anda mungkin menggunakan kelas dengan anggota statis di Jawa.


sumber
6

Objek adalah kelas tetapi sudah memiliki instance, sehingga Anda tidak dapat memanggil new ObjectName. Di sisi lain, Kelas hanya mengetik dan itu bisa menjadi contoh dengan memanggil new ClassName().

Yonggoo Noh
sumber
4

Dalam scala, tidak ada statickonsep. Jadi scala membuat objek tunggal untuk menyediakan titik masuk untuk eksekusi program Anda. Jika Anda tidak membuat objek tunggal, kode Anda akan berhasil dikompilasi tetapi tidak akan menghasilkan output. Metode yang dinyatakan dalam Singleton Object dapat diakses secara global. Objek tunggal dapat memperluas kelas dan sifat.

Contoh Objek Scala Singleton

object Singleton{  
    def main(args:Array[String]){  
        SingletonObject.hello()         // No need to create object.  
    }  
}  


object SingletonObject{  
    def hello(){  
        println("Hello, This is Singleton Object")  
    }  
}  

Keluaran:

Hello, This is Singleton Object

Dalam scala, ketika Anda memiliki kelas dengan nama yang sama dengan objek singleton, itu disebut kelas pendamping dan objek singleton disebut objek pendamping.

Kelas pendamping dan objek pendampingnya keduanya harus didefinisikan dalam file sumber yang sama.

Contoh Objek Pengiring Scala

class ComapanionClass{  
    def hello(){  
        println("Hello, this is Companion Class.")  
    }  
}  
object CompanoinObject{  
    def main(args:Array[String]){  
        new ComapanionClass().hello()  
        println("And this is Companion Object.")  
    }  
}  

Keluaran:

Hello, this is Companion Class.
And this is Companion Object.

Dalam scala, sebuah kelas dapat berisi:

1. Anggota data

2. Metode anggota

3. Blok Konstruktor

4. Kelas bersarang

5. Informasi kelas super dll.

Anda harus menginisialisasi semua variabel instan di kelas. Tidak ada ruang lingkup standar. Jika Anda tidak menentukan ruang lingkup akses, itu publik. Harus ada objek di mana metode utama didefinisikan. Ini memberikan titik awal untuk program Anda. Di sini, kami telah membuat contoh kelas.

Contoh Contoh Scala Kelas

class Student{  
    var id:Int = 0;                         // All fields must be initialized  
    var name:String = null;  
}  
object MainObject{  
    def main(args:Array[String]){  
        var s = new Student()               // Creating an object  
        println(s.id+" "+s.name);  
    }  
} 

Maaf, saya terlambat tetapi saya harap ini akan membantu Anda.

Bhaskar Das
sumber
2

Kelas scala sama dengan Kelas Java tetapi scala tidak memberi Anda metode entri di kelas, seperti metode utama di java. Metode utama yang terkait dengan kata kunci objek. Anda dapat menganggap kata kunci objek sebagai menciptakan objek tunggal kelas yang didefinisikan secara implisit.

informasi lebih lanjut periksa kelas artikel ini dan kata kunci objek dalam pemrograman scala

FOD
sumber
2

Objek ini mirip dengan kelas statis di Jawa untuk beberapa perluasan, karakteristik statis berarti kelas statis tidak perlu membuat objek saat meletakkan ke JVM, dapat digunakan oleh nama kelas itu secara langsung dan contoh yang sama (keadaan data yang sama ) dibagikan di mana pun ia digunakan.

David
sumber
1

Kelas sama seperti kelas lain dalam bahasa lain. Anda mendefinisikan kelas sama seperti bahasa lain dengan beberapa perbedaan sintaksis.

class Person(val name: String)
val me = new Person("My name")

Namun, objek adalah kelas dengan objek tunggal saja. Ini membuatnya menarik karena dapat digunakan untuk membuat anggota statis kelas menggunakan objek pendamping . Objek pendamping ini memiliki akses ke anggota pribadi dari definisi kelas dan memiliki nama yang sama dengan kelas yang Anda tetapkan.

class Person(var name: String) {

  import Person._

  def hi(): String = sayHello(name)
}

object Person {
  private def sayHello(name: String): String = "Hello " + name
}

val me = new Person("My name")
me.hi()

Juga, poin penting adalah bahwa kelas objek dibuat dengan malas yang merupakan poin penting lainnya. Jadi, ini tidak dipakai kecuali mereka diperlukan dalam kode kami.

Jika Anda mendefinisikan pembuatan koneksi untuk JDBC, Anda dapat membuatnya di dalam objek untuk menghindari duplikasi seperti yang kita lakukan di Jawa dengan objek tunggal.

Piyush Patel
sumber
0

Jika Anda berasal dari latar belakang java, konsep class di scala agak mirip dengan Java, tetapi class di scala tidak boleh berisi anggota statis.

Objek dalam scala adalah tipe tunggal yang Anda panggil metode di dalamnya menggunakan nama objek, dalam objek scala adalah kata kunci dan objek java adalah instance dari kelas

Vivek
sumber