【追記あり】Scalaのobjectとclassの違いについての雑な理解とそれに対するご指摘

Scalaのobjectとclassって何が違うのか、よくわかっていなかったのでまとめました。 追記 前半のやり取りが盛大に間違っていたのと、やり取りがたいへんわかりづらいので、がくぞ(@gakuzzzz)さんにご指摘を頂きました。
1

発端

shigemk2 @shigemk2

Scalaのobjectはclassの別名という超絶雑な理解

2015-10-10 15:47:17

前半のやり取り

func @func_hs

@shigemk2 コンパニオンオブジェクトができあがるよ

2015-10-10 15:48:17
shigemk2 @shigemk2

@func_hs 実装ってところで言いますと、コンパニオンオブジェクトができて何が嬉しいのかというと、そのあたりもあまり良くわかっていないんですよね。いくつか便利関数を実装しなくてもいいってところが良い所なのかなと思っているのですが。

2015-10-10 16:03:35
func @func_hs

@shigemk2 ですねぃ。あくまでScalaを書く上で大体必要になるとされているメソッドをこっそり実装してもらうためのものです。Apply()とかUnApply()とか、その辺の。 なのでScalaの構文でよしなにやってもらう必要とかなければ、classでも間に合います。

2015-10-10 16:05:55
shigemk2 @shigemk2

@func_hs objectからコンパニオンオブジェクトが作れるという話ですが、case classからもコンパニオンオブジェクトが作れるという話ですので、違いがよくわかっていないです。

2015-10-10 16:09:54
func @func_hs

@shigemk2 ne.jp/asahi/hishidam… case classはコンストラクタ引数周辺の便利なものまでつけてくれて、objectは単にApplyのtraitが付く感じみたいですね

2015-10-10 16:14:38
shigemk2 @shigemk2

@func_hs case classとobjectでついてくるメソッドが違うというところは理解しました。ちなみに、Applyのtraitとは何でしょうか。

2015-10-10 16:26:11
shigemk2 @shigemk2

@func_hs objectやcase classとは関係ない、というところですね。Functoin1については、「引数が1つの関数」という理解ですが、実際の使いドコロがよくわかっていないです。すみません。

2015-10-10 16:57:37
func @func_hs

@shigemk2 それがあるとね、あたかもコンストラクタを呼んでいるかのようにメソッド経由でインスタンスを生成できるんです。 return new Hoge(foo); や Hoge hoge = new Hoge(foo); から new を省ける程度に思っていただければ。

2015-10-10 17:00:14
func @func_hs

@shigemk2 で、これで何がいいのかというと、Scalaの構文でコンストラクタをラップできるので、オブジェクトのフィールドに(Scalaの)関数オブジェクトを渡したりするみたいなことがるのです。Hoge(foo()) とか Hoge(foo)(bar()) とかとか。

2015-10-10 17:04:49
shigemk2 @shigemk2

@func_hs FunctionNのよいところが呼び出し時にnewが要らないとか、引数に関数オブジェクトを渡すことができるとかそういう利点なんですね。

2015-10-10 17:27:08
func @func_hs

@shigemk2 ですねぇ。詳しくはリファレンスをご覧になるとよいと思いますが、引数や返り値の型がジェネリクスなので、実装の適用範囲をかなり広くできるのも特徴です

2015-10-10 17:28:43
shigemk2 @shigemk2

@func_hs レファレンスを読むと、(T1) => Rって書いてあるので、ここで指定できる型はほぼなんでもよく、IntとかStringみたいなのからFunctionまで可、という理解になりました。

2015-10-10 17:33:39
func @func_hs

@shigemk2 さらに引数側の型は親クラスへの汎化が許されており、返り値の方は子クラスへの特化が許されています。

2015-10-10 17:35:20
shigemk2 @shigemk2

@func_hs それは scala-lang.org/api/2.11.7/#sc… のtrait Function1[-T1, +R] extends AnyRefってところで読み取れる感じですね。

2015-10-10 17:42:52
shigemk2 @shigemk2

@func_hs まとめると、case classやobjectに備わっている関数と、Function1などから連なる階層構造に直接の関係はないですが、FunctionとかAnyとかで用意されている関数はcase classやobjectで使えるという理解です。

2015-10-10 18:06:18
shigemk2 @shigemk2

@func_hs とても参考になる知見を、ありがとうございます。

2015-10-10 18:08:31

まとめを出したあとに、がくぞ(@gakuzzzz)さんからご指摘を頂きました。

shigemk2 @shigemk2

はてなブログに投稿しました #はてなブログ Scalaのobjectはclassの別名という超絶雑な理解だった - by shigemk2 shigemk2.com/entry/scala_ob…

2015-10-10 18:43:47