Scalaのオブジェクトとクラスの違い


636

私はインターネットでいくつかのScalaチュートリアルを調べているところですが、いくつかの例では、例の最初にオブジェクトが宣言されていることに気づきました。

違いは何であるclassobjectScalaのでは?

回答:


580

tl; dr

  • class C JavaまたはC ++と同様に、クラスを定義します。
  • object Oいくつかの匿名クラスのインスタンスとしてシングルトンオブジェクトOを作成します。一部のクラスのインスタンスに関連付けられていない静的メンバーを保持するために使用できます。
  • object O extends TオブジェクトをOのインスタンスにしtrait Tます。その後、Oどこにでも渡すことができますT
  • ある場合はclass C、その後、object CあるコンパニオンオブジェクトクラスのはC、コンパニオンオブジェクトは自動的にはのインスタンスではないことに注意してくださいC

オブジェクトクラスについてはScalaのドキュメントも参照してください。

object 静的メンバーのホストとして

ほとんどの場合、object最初にいくつかのクラスのインスタンスをインスタンス化しなくても使用できるメソッドと値/変数を保持する必要があります。この使用法はstatic、Javaのメンバーと密接に関連しています。

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

次に、を使用して上記のメソッドを呼び出すことができA.twice(2)ます。

twiceあるクラスのメンバーである場合は、A最初にインスタンスを作成する必要があります。

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

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

twiceインスタンス固有のデータを必要としないため、これがどれほど冗長であるかを確認できます。

object 特別な名前付きインスタンスとして

object自身をクラスまたはトレイトの特別なインスタンスとして使用することもできます。これを行うとき、オブジェクトtraitは、そのサブクラスのインスタンスになるために、いくつかを拡張する必要があります。

次のコードを検討してください。

object A extends B with C {
  ...
}

この宣言は、最初の両方を拡張し、匿名(アクセス不可)クラスを宣言Bし、をC、と名付けられ、このクラスの単一のインスタンスをインスタンス化A

この手段は、A型のオブジェクトを期待関数に渡すことができるBC、またはB with C

の追加機能 object

Scalaにはオブジェクトの特別な機能もいくつかあります。公式ドキュメントを読むことをお勧めします

  • def apply(...) 通常のメソッド名なしの構文を有効にします A(...)
  • def unapply(...)カスタムパターンマッチングエクストラクタを作成できます
  • 同じ名前のクラスを伴う場合、オブジェクトは暗黙的なパラメーターを解決するときに特別な役割を引き受けます

38
また、クラスAを定義し、オブジェクトAのすべてのメソッドをクラスAの静的メソッドとして作成します(Javaとのインターフェース用)。(Scala 2.8で修正されたScala 2.7のバグのモジュロ)
Ken Bloom

2
@KenBloomは本当に?私が試しましたが動作しません:scala> Commerce res8:Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <console>:23:error:not found:type Commerce classOf [Commerce] ^ scala> new Commerce < console>:23:error:not found:type Commerce new Commerce ^
Hendy Irawan

3
@ヘンディ:ScalaはCommerceクラスを認識しませんが、JVMとJava言語は認識します。(それobject Foo{ def main(args:Seq[String]) }がプログラムの実行方法と期待される方法です。)
ケンブルーム

3
ziggystarの答えはより正確です。Commerceという名前の対応するクラスが明示的に定義されていない限り、クラスは匿名クラスです(その後、CommerceオブジェクトはCommerceクラスのコンパニオンオブジェクトになります)
Hendy Irawan

3
@DavidApltauer私の答えではカバーできない微妙な点がたくさんあるに違いない。しかし、おそらくこれを読んでいるほとんどの人にとって、それらは重要ではありません。また、オブジェクトをある特性のインスタンスとして渡すことで問題が発生したことは一度もありませんでした。しかし、うまくいくはずです。
ziggystar 2013年

249

A classは定義、説明です。メソッドと他の型の構成の観点から型を定義します。

アンはobject一意であることが保証されたクラスのインスタンス-シングルトンです。objectコード内のすべてについてobject、実装を宣言したクラスから継承する匿名クラスが作成されます。このクラスは、Scalaのソースコードからは見ることができません。

との間には関係がobjectありclassます。同じ名前を共有するオブジェクトは、クラスのコンパニオンオブジェクトと呼ばれます。これが発生すると、それぞれがprivate他方の可視メソッドにアクセスできます。ただし、これらのメソッドは自動的にインポートされません。それらを明示的にインポートするか、クラス/オブジェクト名を前に付ける必要があります。

例えば:

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
お邪魔して申し訳ありませんが、コンパニオンオブジェクトにメソッドをインポートする方法、またはメソッドにプレフィックスを付ける方法について、例を挙げていただけますか?
ithkuil 2010

4
@ithkuil完了。ばかげた例については申し訳ありませんが、私は良くて短いものを考えることができませんでした。
Daniel C. Sobral

Objectでクラスメソッドを使用したい場合はどうなりますか?それは可能でしょうか?クラスのメソッドがあり、それをObjectで使用したい場合、クラスをインポートしようとするとできません。最終的には、コンストラクターを作成して、メソッドを呼び出す必要があります。したがって、コンパニオンオブジェクトを作成すると、インポートを使用してオブジェクトのメソッドにアクセスできますが、その逆はできません。誰かが検証できますか?
piyushGoyal

@piyushGoyal真実ではありません。オブジェクトにdef f(x: X) = ???メソッドがあるxとすると、コンパニオンクラスのプライベートメソッドを呼び出すことができXます。
ダニエルC.ソブラル2015年

ここで関数に渡されるXは、クラスXIのインスタンスの推測ですか?はいの場合、最終的にはオブジェクトxを使用して、def f。のXクラスのメソッドを呼び出します。
piyushGoyal

76

オブジェクトにはインスタンスが1つだけあります(を呼び出すことはできませんnew MyObject)。クラスのインスタンスを複数持つことができます。

オブジェクトは、Javaの静的メソッドおよびフィールドと同じ(およびいくつかの追加の)目的を果たします。


19

多くの人が説明objectしたように、シングルトンインスタンスを定義します。ここで私が信じられていない答えの1つは、objectいくつかの目的に役立つことです。

  • これは、静的メソッドまたは便利なメソッドと見なされるものを含むclass/のコンパニオンオブジェクトにするtraitことができます。

  • モジュールのように機能し、関連する/補助的なタイプや定義などを含みます。

  • class1つまたは複数traitのを拡張することにより、インターフェースを実装できます。

  • sealed traitデータを含まないのケースを表すことができます。この点で、case classパラメーターがない場合よりも正しいと見なされることがよくあります。実装者sealed traitのみのの特殊なケースは、case object多かれ少なかれ列挙型のScalaバージョンです。

  • これは、implicit主導ロジックの証拠として機能します。

  • シングルトンタイプを紹介します。

これは非常に強力で一般的な構成です。Scalaの初心者にとって非常に混乱する可能性があるのは、同じ構成が非常に異なる用途を持つ可能性があることです。また、objectこれらのさまざまな用途の多くを一度に処理できるため、さらに混乱を招く可能性があります。


18

Scalaでオブジェクトを定義することは、静的メソッドのみを持つJavaでクラスを定義することに似ています。ただし、Scalaでは、オブジェクトは別のスーパークラスを拡張し、インターフェースを実装し、クラスのインスタンスのように渡すことができます。(つまり、クラスの静的メソッドに似ていますが、より優れています)。


17

正式な違い-

  1. オブジェクトのコンストラクタパラメータを提供することはできません
  2. オブジェクトはタイプではありません-新しい演算子でインスタンスを作成することはできません。ただし、フィールド、メソッド、スーパークラスの拡張、特性の混在が可能です。

使用法の違い:

  • Scalaには静的なメソッドやフィールドはありません。代わりにを使用してくださいobject。関連クラスの有無にかかわらず使用できます。最初のケースでは、コンパニオンオブジェクトと呼ばれます。必ず:
    1. クラスとオブジェクトの両方に同じ名前を使用する
    2. 同じソースファイルに配置します。
  • プログラムを作成するにはobject、ではなくでmainメソッドを使用する必要がありますclass

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
  • Javaでシングルトンオブジェクトを使用するときにも使用できます。

      
        
      


「オブジェクトのコンストラクタパラメータを指定することはできません」オブジェクトには、コンストラクタのように機能するapply(...)メソッドがあります。これは私を少し混乱させます。
ダニエル

7

オブジェクトのキーワードは次のようである新しいシングルトンタイプ、作成したクラスのみ単一の名前付きインスタンスを持っています。Javaに慣れている場合は、オブジェクトを宣言する、Scalaでをは、匿名クラスの新しいインスタンスを作成することとよく似ています。

ScalaにはJavaのstaticキーワードに相当するものはなく、オブジェクトはJavaの静的メンバーを持つクラスを使用する可能性があるScalaでよく使用されます。


6

オブジェクトはクラスですが、すでにインスタンスを持っているため、を呼び出すことはできませんnew ObjectName。一方、Classは単なる型であり、を呼び出すことでインスタンスにすることができますnew ClassName()


4

Scalaにはstatic概念はありません。そのため、scalaはシングルトンオブジェクトを作成して、プログラム実行のエントリポイントを提供します。シングルトンオブジェクトを作成しない場合、コードは正常にコンパイルされますが、出力は生成されません。シングルトンオブジェクト内で宣言されたメソッドには、グローバルにアクセスできます。シングルトンオブジェクトは、クラスと特性を拡張できます。

Scalaシングルトンオブジェクトの例

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


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

出力:

Hello, This is Singleton Object

scalaでは、シングルトンオブジェクトと同じ名前のクラスがある場合、それはコンパニオンクラスと呼ばれ、シングルトンオブジェクトはコンパニオンオブジェクトと呼ばれます。

コンパニオンクラスとそのコンパニオンオブジェクトは、両方とも同じソースファイルで定義する必要があります。

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

出力:

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

Scalaでは、クラスには以下を含めることができます。

1.データメンバー

2.メンバー方式

3.コンストラクタブロック

4.ネストされたクラス

5.スーパークラス情報など

クラス内のすべてのインスタンス変数を初期化する必要があります。デフォルトのスコープはありません。アクセススコープを指定しない場合、パブリックになります。mainメソッドが定義されているオブジェクトが必要です。これは、プログラムの開始点を提供します。ここでは、クラスの例を作成しました。

クラスのScalaサンプルの例

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

申し訳ありません。手遅れですが、お役に立てば幸いです。


2

ScalaクラスはJavaクラスと同じですが、Javaのメインメソッドのように、クラスのエントリメソッドを提供しません。オブジェクトキーワードに関連付けられたメインメソッド。objectキーワードは、暗黙的に定義されたクラスのシングルトンオブジェクトを作成することと考えることができます。

詳細については、この記事のクラスとScalaプログラミングのオブジェクトキーワードを確認してください。


2

オブジェクトはJavaの静的クラスにある程度似ていますが、静的特性は、静的クラスがJVMに配置するときにオブジェクトを作成する必要がないことを意味し、そのクラス名と同じインスタンスで使用できます(同じデータ状態) )使用される場所はどこでも共有されます。


1

クラスは、他の言語の他のクラスと同じです。他の言語と同じようにクラスを定義しますが、構文に違いがあります。

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

ただし、オブジェクトは単一オブジェクトのみのクラスです。これは、コンパニオンオブジェクトを使用してクラスの静的メンバーを作成するために使用できるため、興味深いものになります。このコンパニオンオブジェクトは、クラス定義のプライベートメンバーにアクセスでき、定義しているクラスと同じ名前を持っています。

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

また、注目すべき点は、オブジェクトクラスが遅延して作成されることです。これは、もう1つの重要な点です。したがって、これらは、コードで必要とされない限りインスタンス化されません。

JDBCの接続作成を定義している場合は、シングルトンオブジェクトを使用するJavaの場合と同じように、オブジェクト内に作成して重複を回避できます。


0

Javaのバックグラウンドを使用している場合、Scalaのクラスの概念はJavaに似ていますが、Scalaのクラスに静的メンバーを含めることはできません。

scalaのオブジェクトは、オブジェクト名を使用してその内部のメソッドを呼び出すシングルトンタイプです。scalaのオブジェクトはキーワードで、javaオブジェクトはクラスのインスタンスです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.