web-dev-qa-db-ja.com

Scalaにおけるオブジェクトとクラスの違い

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

Scalaのclassobjectの違いは何ですか?

575
Steve

tl; dr

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

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

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

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

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

次のコードを見てください。

object A extends B with C {
  ...
}

この宣言は、最初にBCの両方を拡張する無名(アクセス不能)クラスを宣言し、このクラスのAという名前の単一インスタンスをインスタンス化します。

これは、ABC、またはB with C型のオブジェクトを期待する関数に渡されることを意味します。

objectの追加機能

Scalaにはオブジェクトの特別な機能もいくつかあります。私は 公式文書 を読むことを勧めます。

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

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

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

objectclassの間には関係があります。オブジェクトが同じ名前を共有する場合、そのオブジェクトはクラスのコンパニオンオブジェクトであると言われます。これが起こると、それぞれが他方の可視性の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
   }
}
240

オブジェクトは正確に1つのインスタンスを持ちます(new MyObjectを呼び出すことはできません)。 1つのクラスに複数のインスタンスを含めることができます。

オブジェクトは静的メソッドと同じ同じ(およびその他の)目的を果たすJavaのフィールド。

67
Thomas Jung

多くの人が説明したように、objectはシングルトンインスタンスを定義します。ここでの答えの中で私が除外されていると思うことの一つは、objectがいくつかの目的を果たすということです。

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

  • それは、関連する/補助的なタイプや定義などを含む、モジュールのように振る舞うことができます。

  • classまたは1つ以上のtraitを拡張することでインターフェースを実装できます。

  • データを含まないsealed traitのケースを表すことができます。この点で、それはしばしばパラメータなしのcase classより正しいと考えられています。 sealed traitの実装者だけがいるcase objectの特殊なケースは、多かれ少なかれScalaバージョンのenumです。

  • これはimplicit駆動型ロジックの証拠として機能します。

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

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

17
acjay

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

15
Ken Bloom

形式的な違い -

  1. オブジェクトにコンストラクタパラメータを指定することはできません
  2. Objectは型ではありません - 新しい演算子でインスタンスを作成することはできません。しかし、それはフィールド、メソッドを持ち、スーパークラスを拡張し、そして特性を混ぜることができます。

使い方の違い:

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

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



12
irudyak

objectキーワードは、クラスのような新しいシングルトン型を作成しますこれは単一の名前付きインスタンスのみを持ちます。 Javaに精通しているなら、Scalaでオブジェクトを宣言することは、無名クラスの新しいインスタンスを作成することによく似ています。

ScalaにはJavaの静的キーワードと同等のものはなく、オブジェクトは多くの場合、 Scalaでは、Javaの静的メンバーを持つクラスを使用する可能性があります。

4
user2989087

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

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.

スカラでは、クラスは以下を含むことができます。

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
Bhaskar Das

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

2
Yonggoo Noh

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

詳細情報この記事をチェックする scalaプログラミングにおけるクラスとオブジェクトのキーワード

1
FOD

オブジェクトはある程度Javaの静的クラスに匹敵し、静的な特性は静的クラスがJVMに置くときオブジェクトを作成する必要がないことを意味し、それはそのクラス名で直接使用できます。

0
David

あなたがJavaのバックグラウンドから来ているのであれば、scalaのクラスの概念はJavaと似たようなものですが、scalacantのクラスは静的メンバーを含みます。

Scalaのオブジェクトは、オブジェクト名を使ってその中のメソッドを呼び出すシングルトン型です。scalaのオブジェクトはキーワード、Javaのオブジェクトはクラスのインスタンスです。

0
Vivek

クラスは、他の言語の他のクラスとまったく同じです。他の言語と同じように、クラスにいくつかの構文の違いを定義します。

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

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

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

0
Piyush P