2017-09-27 3 views
1

Dire que j'ai open class C(val c:C) et je veux sous-classe comme class D():C(this)Passant « ce » à un constructeur

C'est invalide selon le compilateur car 'this' is not defined in this context

Y at-il un moyen d'obtenir ce qu'il faut faire ce que je vouloir? Plus précisément, je voudrais que D ait un constructeur qui puisse être appelé sans aucun argument et passera l'objet D en cours de construction au constructeur de C. Dans mon cas, c'est bien que cet objet ne soit pas encore entièrement construit.

Je suis ouvert à toutes les solutions qui n'impliquent pas de changer C, réflexion incluse.

+2

Le vérificateur JVM est mandaté pour rejeter tout code qui tente d'utiliser un '(la référence' this' avant que le constructeur super classe ait été appelé) où une instance initialisée est requise (comme un paramètre du constructeur) . Sans changer 'C', il ne peut pas y avoir de solution de langage ... Ou bien, cela dépend de * pourquoi * vous en avez besoin ou de ce que le constructeur de' C' est supposé faire avec cette référence 'C' ... – Holger

+0

le commentaire! Je l'accepterais volontiers comme une réponse si c'est vraiment le cas. Pour moi, le constructeur de 'C' stocke seulement la référence pour une utilisation ultérieure après la construction, donc j'espérais que cela pourrait être fait, mais le fait qu'il ne peut pas est une réponse utile en soi. –

+1

Puisque vous avez dit "réflexion incluse", vous pouvez écraser le champ * après le retour du superconstructeur. La priorité d'accès inclut la possibilité d'écraser les champs d'instance 'final'. Vous devez d'abord passer une valeur fictive au constructeur de la superclasse, si elle n'autorise pas 'null'. – Holger

Répondre

2

Il n'y a pas de solution simple, car cela ne semble pas être une bonne idée.

Le constructeur de la super classe est exécuté avant que le constructeur de la classe ne le fasse (more details here). Passer ainsi une instance qui n'a pas été initialisée du tout au super constructeur à la place d'une instance valide peut casser une partie de la logique du super constructeur (par exemple, il peut s'attendre à ce que les propriétés de c aient des valeurs significatives, mais elles 't).

Si vous avez besoin de ce si mauvais, vous pouvez essayer de créer une instance de D d'abord avec certains faux/default C, puis créer un autre D avec le premier:

class D(c: C) : C(c) 

fun createD(defaultC: C): D { 
    val firstD = D(defaultC) 
    return D(firstD) 
} 

Bien que cela ne certainement couvre pas tous les cas d'utilisation possibles.