Scala'da nesne ve sınıf arasındaki fark


636

İnternetteki bazı Scala derslerini inceliyorum ve bazı örneklerde bir nesnenin örneğin başında bildirildiğini fark ettim.

Scala arasındaki classve objectarasındaki fark nedir ?

Yanıtlar:


579

tl; Dr.

  • class C Java veya C ++ 'da olduğu gibi bir sınıfı tanımlar.
  • object Oanonim bir sınıfın örneği olarak tek bir nesne oluşturur O; bazı sınıf örnekleri ile ilişkili olmayan statik üyeleri tutmak için kullanılabilir.
  • object O extends Tnesneyi Obir örneği yapar trait T; daha sonra Oherhangi bir yere geçebilirsiniz , a Tbekleniyor.
  • bir varsa class C, o zaman object Cbir tamamlayıcı nesne sınıfı C; tamamlayıcı nesnenin otomatik olarak bir örneği olmadığını unutmayın C.

Ayrıca nesne ve sınıf için Scala belgelerine bakın .

object statik üyelerin ev sahibi olarak

Çoğu zaman, objectönce bir sınıfın örneğini başlatmak zorunda kalmadan kullanılabilecek yöntemleri ve değerleri / değişkenleri saklamanız gerekir. Bu kullanım staticJava üyeleriyle yakından ilgilidir .

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

Daha sonra kullanarak yukarıdaki yöntemi çağırabilirsiniz A.twice(2).

Bir twicesınıfın üyesi Aolsaydınız, önce bir örnek oluşturmanız gerekir:

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

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

twiceHerhangi bir örneğe özgü veri gerektirmediği için bunun ne kadar gereksiz olduğunu görebilirsiniz .

object özel olarak adlandırılmış bir örnek olarak

objectKendini bir sınıf veya özelliğin özel bir örneği olarak da kullanabilirsiniz . Bunu yaptığınızda, nesnenizin traitalt sınıfının bir örneği olabilmesi için bazılarını genişletmesi gerekir.

Aşağıdaki kodu göz önünde bulundurun:

object A extends B with C {
  ...
}

Bu açıklama ilk ikisi uzanan anonim (erişilemez) sınıfı bildirir Bve Cve adlandırılmış bu sınıfın tek bir örneğini başlatır A.

Bu araçlar Atüründeki nesneleri bekliyor işlevlerine geçirilebilir Bveya Cya B with C.

Ek Özellikleri object

Scala'da nesnelerin bazı özel özellikleri de var. Resmi belgeleri okumanızı tavsiye ederim .

  • def apply(...) olağan yöntem adsız sözdizimini etkinleştirir A(...)
  • def unapply(...)özel desen eşleme çıkarıcılar oluşturmanıza olanak tanır
  • aynı ada sahip bir sınıfa eşlik ediyorsa, nesne örtük parametreleri çözerken özel bir rol üstlenir

38
Ayrıca A sınıfı tanımlayacak ve A nesnesindeki tüm yöntemleri A sınıfı üzerinde statik yöntemler olarak oluşturacaktır (Java ile arabirim için). (Modcala Scala 2.7'de Scala 2.8'de düzeltilen bir hata)
Ken Bloom

2
@KenBloom gerçekten mi? Denedim ve çalışmıyor: scala> Commerce res8: Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <console>: 23: hata: bulunamadı: type Commerce classOf [Commerce] ^ scala> new Commerce < konsol>: 23: hata: bulunamadı: tip Ticaret yeni Ticaret ^
Hendy Irawan

3
@Hendy: Scala Commercesınıfı tanımayacak , ancak JVM ve Java dili tanıyacak. ( object Foo{ def main(args:Seq[String]) }Programın böyle çalışmasını bekleyebilirsiniz.)
Ken Bloom

3
Sanırım ziggystar'ın cevabı daha kesin, Ticaret adlı karşılık gelen bir sınıf açıkça tanımlanmadığı sürece sınıf anonim bir sınıftır (o zaman Ticaret nesnesi Ticaret sınıfına eşlik eden bir nesne olacaktır)
Hendy Irawan

3
@DavidApltauer Eminim cevabım kapsamında olmayan yeterince incelik vardır. Ama muhtemelen bunu okuyan çoğu insan için önemli değil. Ve hiçbir özelliği, bir varlığın örneği olarak geçirme konusunda hiç sorun yaşamadım, bu onların var olmadığı anlamına gelmez; ama işe yaramalı.
ziggystar

249

A classbir tanımdır, bir tanımdır. Bir türü yöntemler ve diğer türlerin bileşimi açısından tanımlar.

An objectbir singleton - benzersiz olduğu garanti edilen bir sınıf örneğidir. Koddaki her objectbiri için, objectuyguladığınızı bildirdiğiniz sınıflardan miras kalan anonim bir sınıf oluşturulur . Bu sınıf Scala kaynak kodundan görülemez - buna rağmen yansıma yoluyla alabilirsiniz.

Arasında bir ilişki vardır objectve class. Bir nesnenin, aynı adı paylaşmaları durumunda bir sınıfın tamamlayıcı nesnesi olduğu söylenir. Bu olduğunda, her birinin privatediğerinde görünürlük yöntemlerine erişimi vardır . Ancak bu yöntemler otomatik olarak içe aktarılmaz. Bunları açıkça içe aktarmanız veya sınıf / nesne adıyla ön ek yapmanız gerekir.

Örneğin:

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
   }
}

1
Rahatsız ettiğim için üzgünüm, ancak yöntemleri tamamlayıcı nesneye nasıl aktaracağınıza veya nasıl önek ekleyeceğinize dair bir örneğe işaret edebilir misiniz?
ithkuil

4
@ithkuil Tamamlandı. Aptal örnek için üzgünüm, iyi ve kısa bir örnek düşünemedim.
Daniel C.Sobral

Nesne'de sınıf yöntemini kullanmak istersem ne olur? bu mümkün olabilir mi? Bir sınıfın yöntemim varsa ve bunu Object içinde kullanmak istiyorsanız, o zaman sınıfı içe aktarmaya çalışırsanız, bunu yapamazsınız. Sonunda bir yapıcı yapmalı ve yöntemi çağırmalısınız. Böylece, tamamlayıcı bir nesne oluşturarak, içe aktarma özelliğini kullanarak Nesne yöntemlerine erişebilirsiniz, bunun tersi de mümkün değildir. Birisi lütfen doğrulayabilir mi?
piyushGoyal

@piyushGoyal Doğru değil. Nesnenin bir yöntemi olduğunu varsayalım def f(x: X) = ???, o zaman xtamamlayıcı sınıfın özel yöntemlerini çağırabilirdi X.
Daniel

Burada X işlevinde geçen sınıf XI sanırım örneğidir? Cevabınız evet ise, sonuçta x nesnesini def sınıfındaki X sınıfı yöntemini çağırmak için kullanıyorsunuz.
piyushGoyal

76

Bir nesnenin tam olarak bir örneği vardır (çağıramazsınız new MyObject). Bir sınıfın birden çok örneğine sahip olabilirsiniz .

Nesne , Java'daki statik yöntemler ve alanlarla aynı (ve bazı ek) amaçlara hizmet eder .


19

Birçok kişi tarafından açıklandığı gibi, objecttekil bir örneği tanımlar. Buradaki cevaplarda dışarıda kaldığına inandığım tek şey, objectbirkaç amaca hizmet ediyor olması.

  • Statik yöntemler veya uygunluk yöntemleri olarak düşünülebilecek şeyleri içeren bir class/ nesnesine eşlik eden nesne traitolabilir.

  • İlgili / yardımcı türleri ve tanımları vb. İçeren bir modül gibi davranabilir.

  • Bir classveya bir veya daha fazla traits genişleterek bir arabirim uygulayabilir .

  • sealed traitVeri içermeyen bir durumu temsil edebilir . Bu bakımdan, genellikle case classparametresiz bir a'dan daha doğru kabul edilir . sealed traitSadece case objectuygulayıcıları olan özel bir durum , bir numaralandırmanın aşağı yukarı Scala versiyonudur.

  • implicitTahriş olmuş mantığın kanıtı olabilir .

  • Tekli bir tip sunar.

Çok güçlü ve genel bir yapı. Scala yeni başlayanlar için çok kafa karıştırıcı olabilecek şey, aynı yapının çok farklı kullanımlara sahip olabileceğidir. Ve objectbu farklı kullanımların birçoğuna aynı anda hizmet edebilir, bu da daha da kafa karıştırıcı olabilir.


18

Scala'da bir nesne tanımlamak, Java'da yalnızca statik yöntemlere sahip bir sınıf tanımlamak gibidir. Bununla birlikte, Scala'da bir nesne başka bir üst sınıfı genişletebilir, arayüzleri uygulayabilir ve sanki bir sınıf örneğiymiş gibi aktarılabilir. (Yani bir sınıftaki statik yöntemler gibi ama daha iyisi).


17

Resmi fark -

  1. Nesneler için yapıcı parametreleri sağlayamazsınız
  2. Nesne bir tür değil - yeni işleç ile örnek oluşturamayabilirsiniz. Ancak alanları, yöntemleri olabilir, bir üst sınıfı genişletebilir ve özelliklerle karışabilir.

Kullanımdaki fark:

  • Scala'nın statik yöntemleri veya alanları yoktur. Bunun yerine kullanmalısınız object. İlgili sınıfla veya sınıfsız kullanabilirsiniz. 1. durumda buna yardımcı nesne denir. Yapmalısın:
    1. hem sınıf hem de nesne için aynı adı kullan
    2. aynı kaynak dosyaya koyun.
  • Bir program oluşturmak için objectdeğil, ana yöntemi kullanmalısınız class.

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
  • Java'da singleton nesnesi kullandığınızda da kullanabilirsiniz.

      
        
      


"Nesneler için yapıcı parametreleri sağlayamazsınız" Nesneler, bir kurucuya çok benzer şekilde işlev gören Apply (...) yöntemine sahiptir. Bu beni biraz karıştırıyor.
Danielle

7

Nesne anahtar bir benzeri olan yeni tekil türünü yaratan sınıfın sadece tek adlandırılmış örneği vardır. Java'ya aşina iseniz , Scala'da bir nesne bildirmek, anonim bir sınıfın yeni bir örneğini oluşturmak gibidir.

Scala, Java'nın statik anahtar kelimesine eşdeğer değildir ve Scala'da genellikle Java'da statik üyelere sahip bir sınıf kullanabileceğiniz bir nesne kullanılır.


6

Nesne bir sınıftır, ancak zaten bir örneğidir (yani), yani çağıramazsınız new ObjectName. Öte yandan, Class sadece türdür ve arayarak bir örnek olabilir new ClassName().


4

Skala'da bir statickavram yoktur . Bu nedenle scala, program yürütmeniz için giriş noktası sağlamak üzere tek bir nesne oluşturur. Singleton nesnesi oluşturmazsanız, kodunuz başarıyla derlenir ancak çıktı üretilmez. Singleton Object içinde bildirilen yöntemlere global olarak erişilebilir. Tek bir nesne, sınıfları ve özellikleri genişletebilir.

Scala Singleton Nesne Örneği

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


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

Çıktı:

Hello, This is Singleton Object

Scala'da, singleton nesnesiyle aynı ada sahip bir sınıfınız varsa, buna companion sınıfı ve singleton nesnesine companion nesnesi denir.

Tamamlayıcı sınıf ve tamamlayıcı nesnesinin her ikisi de aynı kaynak dosyada tanımlanmalıdır.

Scala Yardımcı Nesne Örneği

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.")  
    }  
}  

Çıktı:

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

Scala dilinde bir sınıf şunları içerebilir:

1. Veri üyesi

2. Üye yöntemi

3. Oluşturucu Bloğu

4. İç içe sınıf

5. Süper sınıf bilgileri vb.

Sınıftaki tüm örnek değişkenleri başlatmalısınız. Varsayılan kapsam yoktur. Erişim kapsamını belirtmezseniz, herkese açıktır. Ana yöntemin tanımlandığı bir nesne olmalıdır. Programınız için başlangıç ​​noktası sağlar. Burada bir sınıf örneği oluşturduk.

Scala Sınıf Örneği Örneği

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);  
    }  
} 

Üzgünüm, çok geç kaldım ama umarım size yardımcı olacaktır.


2

Scala sınıfı Java Sınıfı ile aynıdır ancak scala, java'daki ana yöntem gibi sınıfta herhangi bir giriş yöntemi vermez. Nesne anahtar kelimesi ile ilişkili ana yöntem. Object anahtar sözcüğünü, örtülü olarak tanımlanan bir sınıfın tekli nesnesini oluşturmak olarak düşünebilirsiniz.

daha fazla bilgi scala programlamada bu makale sınıfını ve nesne anahtar sözcüğünü kontrol edin


2

Nesne, Java'daki statik sınıfa biraz uzanır, statik karakteristik, statik sınıfın JVM'ye koyarken bir nesne oluşturması gerekmediği anlamına gelir, doğrudan sınıf adı ve aynı örnek tarafından kullanılabilir (aynı veri durumu) ) kullanıldığı her yerde paylaşılır.


1

Sınıf, diğer dillerdeki diğer sınıflar gibidir. Sınıfı, diğer sözdizimi farkları olan diğer diller gibi tanımlarsınız.

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

Ancak, nesne yalnızca tek nesneli bir sınıftır. Bu, onu tamamlayıcı nesne kullanarak bir sınıfın statik üyeleri oluşturmak için kullanılabileceği için ilginç kılar . Bu tamamlayıcı nesne, sınıf tanımının özel üyelerine erişebilir ve tanımladığınız sınıfla aynı ada sahiptir.

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()

Ayrıca, dikkat çeken nokta, bir başka önemli nokta olan nesne sınıfının tembel olarak yaratılmış olmasıdır. Bu nedenle, kodumuzda gerekli olmadıkça bunlar somutlaştırılmaz.

JDBC için bağlantı oluşturmayı tanımlıyorsanız, Java'da tekil nesnelerle yaptığımız gibi çoğaltmayı önlemek için bunları nesnenin içinde oluşturabilirsiniz.


0

Java geçmişinden geliyorsanız scala'daki sınıf kavramı Java'ya benzerdir, ancak scala'daki sınıf statik üyeler içeremez.

Scala içindeki nesneler, nesne adını kullanarak içindeki yöntemleri çağırdığınız tekli türdür, scala nesnesindeki bir anahtar kelime ve java nesnesindeki sınıfın bir örneğidir

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.