Scalaの「新しい」キーワード


93

非常に簡単な質問があります。Scalaでオブジェクトを作成するときに、いつ新しいキーワードを適用すればよいですか?Javaオブジェクトのみをインスタンス化しようとしたときですか?

回答:


144

独自のコンストラクタnewを参照する場合は、キーワードを使用しますclass

class Foo { }

val f = new Foo

newコンパニオンオブジェクトのapplyメソッドを参照している場合は省略します。

class Foo { }
object Foo {
    def apply() = new Foo
}

// Both of these are legal
val f = Foo()
val f2 = new Foo

ケースクラスを作成した場合:

case class Foo()

Scalaは密かにあなたのためにコンパニオンオブジェクトを作成し、これを次のように変えます。

class Foo { }
object Foo {
    def apply() = new Foo
}

だからできる

f = Foo()

最後に、コンパニオンapply メソッドはコンストラクタのプロキシでなければならないというルールはないことに注意してください。

class Foo { }
object Foo {
    def apply() = 7
}

// These do different things
> println(new Foo)
test@5c79cc94
> println(Foo())
7

そして、Javaクラスについて言及したので、はい。Javaクラスにはapplyメソッドを持つコンパニオンオブジェクトがほとんどないためnew、実際のクラスのコンストラクターを使用する必要があります。


1
Javaクラスにコンパニオンオブジェクトを含めることはできません。Javaクラスのファクトリとして機能するオブジェクトを持つことができますが、このオブジェクトはそのコンパニオンオブジェクトではありません。
きりつく

@Antoras ScalaクラスはJavaバイトコードにコンパイルされ、コンパイルされた形式で配布できるので、Scalaは実際のScalaコンパニオンと静的なMODULE $メンバーを持つFoo $というクラスの違いを認識できますか?
オーウェン

1
コンパニオンオブジェクトは、コンパニオンクラスと同じファイルで宣言する必要があることが仕様化されているため、スカラックはこれとは異なる場合があると思います。コンパニオンの「プロパティ」はScalaにのみ存在し、バイトコードレベルには存在しないため、スカラーはバイトコードではなくScalaコードをチェックして、仕様に準拠していることを確認する必要があります。
キリツク

1
Scalaで新しいキーワードを使用しないJavaクラスの例はありますか?
Bober02 2012年

また、コンパニオンオブジェクトのメソッドは、クラスの静的メソッドを介してもアクセス可能になり、後で「コンパニオン」を定義するJavaクラスではこれは起こりません。
drexin 2012年

16

Javaオブジェクトのみをインスタンス化しようとしたときですか?

どういたしまして。newscalaで省略した場合、2つの一般的なケースがあります。シングルトンオブジェクト(静的関数を格納するためによく使用され、Javaで見られるものと同様の一種のファクトリーとして):

scala> object LonelyGuy { def mood = "sad" }
defined module LonelyGuy

scala> LonelyGuy
res0: LonelyGuy.type = LonelyGuy$@3449a8

scala> LonelyGuy.mood
res4: java.lang.String = sad

ケースクラス場合(実際には、クラス+オブジェクト= コンパニオンパターンがあります。たとえば、クラスとオブジェクトが同じ名前である場合):

scala> case class Foo(bar: String) 
defined class Foo


scala> Foo("baz")
res2: Foo = Foo(baz)

したがって、単純なクラスで作業する場合、ルールはJavaの場合と同じです。

scala> class Foo(val bar: String) 
defined class Foo

scala> new Foo("baz")
res0: Foo = Foo@2ad6a0

// will be a error 
scala> Foo("baz")
<console>:8: error: not found: value Foo
       Foo("baz")

おまけに、次のように構築できる匿名クラスがscalaにあります。

scala> new { val bar = "baz" }
res2: java.lang.Object{val bar: java.lang.String} = $anon$1@10ee5b8

scala> res2.bar
res3: java.lang.String = baz

1
大丈夫、つぼみ?
ジェイコブB

0

Javaオブジェクトのみをインスタンス化しようとしたときですか?

Dottyベースの Scala 3(2020年半ば、8年後のリリース予定):決して。

このスレッドのnewよう、Scala 3は " " をドロップします

Creatorアプリケーションでは、applyメソッドが実装されていなくても、単純な関数呼び出し構文を使用してクラスのインスタンスを作成できます。

例:

class StringBuilder(s: String) {
   def this() = this(s)
}

StringBuilder("abc")  // same as new StringBuilder("abc")
StringBuilder()       // same as new StringBuilder()

クリエーターアプリケーションは、これまでケースクラスにのみ提供されていた機能を一般化していますが、これを実現するメカニズムは少し異なります。
自動生成された適用メソッドの代わりに、新しい可能な解釈を関数呼び出しに追加しますf(args)

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