scalaにおけるclass,object,traitの違い

4026 ワード

1.object
objectの特徴は:1.属性とメソッドを持つことができ、デフォルトは「static」タイプで、newから出てくるオブジェクト(サポートされていない)を必要とせずにobject名で直接属性とメソッドを呼び出すことができます.2.objectのmain関数式アプリケーションのエントリ.3.objectとclassにはclassと同じ場所がたくさんあり、extends親クラスまたはTraitができますが、objectはextends objectができません.つまりobjectは親として機能しません.
2.class
1つのプライマリコンストラクタ(関数)であり、他はセカンダリコンストラクタのインプリメンテーションであり、プライマリコンストラクタのパラメータを参照(呼び出す)必要があります.クラスの属性セカンダリコンストラクタの名前にもなります.thisセカンダリコンストラクタでは、他のセカンダリコンストラクタまたはプライマリコンストラクタの呼び出しで開始する必要があります.コンストラクタ
生成されたフィールドメソッドname:Stringオブジェクトプライベートフィールド.nameを使用する方法がない場合は、このフィールドはありません.Private val/var name Stringプライベートフィールド、プライベートgetter/setterメソッド.Val/var name:Stringプライベートフィールド、公開getter/setterメソッド
scalaクラスにはstaticメソッドはありませんが、どのようにしてクラスを実現するかは普通のメソッドと静的メソッドがありますか?伴生オブジェクトはこの要件を満たすことができ、伴生クラスと伴生オブジェクトは互いにプライベートメンバーにアクセスすることができる.
class TestClass(val id: Int) {

    def this(id1: Int, id2: Int) {
        this(id1)
    }

    def add2(a: Int, b: Int) = {
        a + b
    }
}

object TestClass {

    def apply(id: Int)= {
        println("-----------apply--------")
        new TestClass(id)
    }

    def add(a: Int, b: Int): Int = {
        a + b
    }

    def main(args: Array[String]): Unit = {
        val r1 = TestClass.add(1, 2)
        println(s"r1 is: $r1")

        val t1 = new TestClass(1)
        val r2 = t1.add2(3, 4)
        println(s"r2 is: $r2")

        val t2 = TestClass(100000)
        println(s"t2.id is: ${t2.id}")

        val t3 = new TestClass(100, 200)
        println((s"t3.id is: ${t3.id}"))
    }
}


出力結果:
r1 is: 3
r2 is: 7
-----------apply--------
t2.id is: 100000
t3.id is: 100

3.trait
ScalaのTraitはJavaのInterfaceに相当するが,Traitは関数を定義するだけでなく,関数体実装も可能である.実装キーワードはextendsであり,複数のTrait用withを実装する.extendsの複数のTraitに同じ関数がある場合、サブクラスはその関数を書き直さなければなりません.
親traitには関数体の関数がなく、サブクラスはoverrideで親クラスに関数体の関数があることを書き換えなければならない.キーワードoverride traitの変数がある必要がある.valタイプがtraitで定義した変数であり、valタイプでなければならない.変数が初期化されていない場合、サブクラスはoverrideでなければならない.
trait TestTrait {
    def printfun()
}

class TestTraitImp extends TestTrait {
    override def printfun(): Unit = {
        println("I'm TestTrait implement!")
    }
}

object TestClass {
	def main(args: Array[String]): Unit = {
	    val t4 = new TestTraitImp()
        t4.printfun()
    }
}

実行結果は
I'm TestTrait implement!

4.scalaクラス階層
Scalaでは,各クラスが共通のAnyというスーパークラスから継承される.すべてのクラスがAnyのサブクラスであるため、Anyに定義されたメソッドは「共通」メソッドです.任意のオブジェクトによって呼び出されます.
Anyには2つのサブクラスがある:AnyValとAnyRef(JavaのObjectに相当).
AnyValはScala内の各組み込み値クラスの親です.Byte、Short、Char、Int、Long、Float、Double、Boolean、Unitの9つの値クラスがあります.このうち上位8つは、Javaの基本タイプに対応しています.これらの値クラスは抽象的でfinal的であり、newを使用してクラスのインスタンスを作成することはできません.Unitは、結果を返さないメソッドの結果タイプとして使用されます.Unitはインスタンス値が1つしかなく、()と書きます.AnyRefクラスはScala内のすべての参照クラス(reference class)のベースクラスである.実はJavaプラットフォームのjavaです.lang.Objectクラスの別名.そのためJavaに書かれているクラスもScalaに書かれているクラスもAnyRefから継承されています.scala.Nullとscala.Nothingは、Scalaがオブジェクトタイプシステムに向かういくつかの「境界状況」を統一的に処理する特殊なタイプです.Nullクラスはnull参照オブジェクトのタイプであり、各参照クラス(AnyRefから継承されたクラス)のサブクラスである.Nullは値タイプに互換性がありません.NothingタイプはScalaのクラスレベルの最下位にあります.他のタイプのサブタイプです.しかし、このタイプの値はまったくありません.Nothingの1つの用途は、異常な終了を示すことです.
5.scala単例モードの実現
scalaにはstaticがないので,単一例モードを伴生オブジェクトで実現した.
class SingleModel {
    def printfunc() = {
        println("this is SingleModel!")
    }

}

object SingleModel {
    private var instance: SingleModel = null

    def getInstance() = {
        if (instance == null) {
            this.synchronized {
                if (instance == null) {
                    instance = new SingleModel()
                }
            }
        }
        instance
    }
}

クライアント呼び出しのコードは次のとおりです.
object SingleModelClient {

    def main(args: Array[String]): Unit = {
        val instance = SingleModel.getInstance()
        instance.printfunc()
    }
}

最後の出力は
this is SingleModel!