J'ai une question très simple: quand devons-nous appliquer le nouveau mot-clé lors de la création d'objets dans Scala? Est-ce lorsque nous essayons d'instancier uniquement des objets Java?
Réponses:
Utilisez le new
mot - clé lorsque vous souhaitez faire référence au class
propre constructeur d'un:
class Foo { }
val f = new Foo
Omettez new
si vous faites référence à la apply
méthode de l'objet compagnon :
class Foo { }
object Foo {
def apply() = new Foo
}
// Both of these are legal
val f = Foo()
val f2 = new Foo
Si vous avez créé une classe de cas:
case class Foo()
Scala crée secrètement un objet compagnon pour vous, le transformant en ceci:
class Foo { }
object Foo {
def apply() = new Foo
}
Alors tu peux faire
f = Foo()
Enfin, gardez à l'esprit qu'aucune règle ne dit que la apply
méthode compagnon doit être un proxy pour le constructeur:
class Foo { }
object Foo {
def apply() = 7
}
// These do different things
> println(new Foo)
test@5c79cc94
> println(Foo())
7
Et, puisque vous avez mentionné les classes Java: oui - Les classes Java ont rarement des objets compagnons avec une apply
méthode, vous devez donc utiliser new
et le constructeur de la classe réelle.
Est-ce lorsque nous essayons d'instancier uniquement des objets Java?
Pas du tout. Il y a deux cas généraux lorsque vous ommit new
dans scala. Avec des objets singleton (qui sont souvent utilisés pour stocker des fonctions statiques et comme une sorte d'usine similaire à ce que vous pouvez voir en 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
Avec une classe de cas (en fait, en dessous, il y a classe + objet = modèle compagnon , par exemple ayant une classe et un objet avec le même nom):
scala> case class Foo(bar: String)
defined class Foo
scala> Foo("baz")
res2: Foo = Foo(baz)
Ainsi, lorsque vous travaillez avec des classes simples, les règles sont les mêmes qu'avec 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")
Bonus, il y a une classe anonyme dans scala, qui peut être construite comme ceci:
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
Est-ce lorsque nous essayons d'instancier uniquement des objets Java?
Avec Scala 3 (qui devrait sortir mi 2020, huit ans plus tard), basé sur Dotty : jamais.
Scala 3 supprimera " new
", comme dans ce fil
Les applications Creator permettent d'utiliser une simple syntaxe d'appel de fonction pour créer des instances d'une classe, même si aucune méthode apply n'est implémentée.
Exemple:
class StringBuilder(s: String) {
def this() = this(s)
}
StringBuilder("abc") // same as new StringBuilder("abc")
StringBuilder() // same as new StringBuilder()
Les applications de création généralisent une fonctionnalité fournie jusqu'à présent uniquement pour les classes de cas, mais le mécanisme permettant d'y parvenir est légèrement différent.
Au lieu d'une méthode apply auto-générée, nous ajoutons une nouvelle interprétation possible à un appel de fonctionf(args)
.