【追記あり】Scalaのobjectとclassの違いについての雑な理解とそれに対するご指摘
@gakuzzzz すみません。一つ一つ理解しようと思って色々質問してたら、話が拡散してしまいました。Function1のくだりは直接関係ないのにそのあたりについても質問してしまったので、端から見たら追いかけづらい会話になってしまってます。
2015-10-10 19:11:37@gakuzzzz ご指摘ありがとうございます。後学のために、どこが間違っててどこが正しいのか教えて頂けますでしょうか。お手数おかけします。
2015-10-10 19:25:34@shigemk2 まず、class は型を定義するもので object は値を定義するもので全く違う構文です。 意味合い的に object Foo とすると val Foo = new AnyRef { } に近い意味になります(厳密には違いますが)
2015-10-10 19:26:41@shigemk2 class Foo とすると 型Foo ができて、val Bar = new Foo とするとfooという変数にFoo型の値が代入されます。 object Foo とすると、 Fooという変数にFoo.type型の値が代入されます。た
2015-10-10 19:31:00@shigemk2 本来、Foo型と Foo.type型は違う型です。なのでFoo型にprivateなメンバが存在していても、Foo.type からはそのメンバにはアクセスする事ができません。しかしclass Fooとobject Fooが同一のファイルに定義されていたとき
2015-10-10 19:32:59@shigemk2 その両者は特別な関係を持ち、両者のprivateなメンバにアクセスできるという特例が与えられます。この関係をさして、object Fooはclass Fooのコンパニオンオブジェクト、class Fooはobject Fooのコンパニオンクラスと言います
2015-10-10 19:34:34@shigemk2 で、case class Foo() とすると、自分で書かなくても自動的にobject Fooが定義され、いくつかのメソッドがFoo型とFoo.type型に定義されます。この際、Foo.type型はFunctionNのサブクラスになっています。
2015-10-10 19:37:32@shigemk2 また、case class Foo() を定義した際に、明示的に自分で object Foo を定義する事も可能です。その場合は同様にFoo.type型にいくつかのメソッドが自動で定義されます。ただしその場合、
2015-10-10 19:40:00@gakuzzzz なので、case classもobjectもコンパニオンオブジェクトと呼ばれるのですね。先の例に則ると、class Fooのコンパニオンオブジェクトに。
2015-10-10 19:40:09@shigemk2 明示的にobject Foo extends Function1[String, Foo] などと書かない限り、Foo.typeはFunctionNのサブクラスにはなりません。
2015-10-10 19:40:38@shigemk2 case class を定義すると自動的にコンパニオンオブジェクトが定義される、というだけで case classをコンパニオンオブジェクトと呼ぶのは明確に間違いです
2015-10-10 19:42:14@shigemk2 またobjectも同名のclassが存在しているのであればそのclassのコンパニオンオブジェクトと呼ぶことはできますが、同名のクラスが無い場合にコンパニオンオブジェクトと呼ぶのは間違いです。
2015-10-10 19:44:25@gakuzzzz 色々とありがとうございます。無理くりclassとobjectとcase classをコンパニオンオブジェクトという言葉でもって同一視したのが間違いのようです。
2015-10-10 20:08:41@shigemk2 はい。あくまでコンパニオンオブジェクトはobjectが特定の条件を満たした場合に、コンパニオンオブジェクトとも呼べるというだけですね。
2015-10-10 20:11:53@gakuzzzz 前提として、当たり前ですが、objectとclassは全くの別物、というところから始めないといけない理解です。
2015-10-10 20:14:57@gakuzzzz @func_hs 件のブログ記事ですが、要点1と2はともかく、要点3は後から読んで本当に意味不明でした。 shigemk2.com/entry/scala_ob…
2015-10-10 20:20:08