2
votes

étendre la valeur par défaut de la classe du paramètre parent

J'ai la classe B avec aux paramètres x et y étendue de la classe A avec le paramètre x qui est facultatif (tous les parmaters sont non nuls) comment puis-je définir B de manière à ce qu'il soit facultatif et qu'il utilise la valeur facultative dans le constructeur de A

val y = 0
val b = if (y == 0) B(y) else B(y, 0)

class B(y: Int, x: Int = 238) : A(x)

open class A(x: Int = 238)

ici, j'ai défini la valeur par défaut pour x dans le constructeur de B y a-t-il un moyen d'y parvenir sans avoir à définir la valeur par défaut dans B


0 commentaires

3 Réponses :


2
votes

Vous pouvez y parvenir avec des constructeurs secondaires.

class B : A {
    constructor(y: Int): super()
    constructor(y: Int, x: Int): super(x)
}

Pour plus d'informations, consultez Kotlin Docs .

Edit:

Comme @PietroMartinelli le mentionne, les constructeurs secondaires ne fonctionneraient pas si vous avez besoin d'un constructeur principal. Si la classe dérivée a un constructeur principal, la classe de base peut (et doit) être initialisée à cet endroit, en utilisant les paramètres du constructeur principal.


3 commentaires

Cette approche ne fonctionne pas lorsque vous devez (ou voudriez) définir un constructeur primaire non vide dans la sous-classe B , n'est-ce pas?


@PietroMartinelli C'est vrai. Avec le constructeur principal, la classe doit être initialisée immédiatement pour que cela ne fonctionne pas.


Ok, c'est quand même une belle approche, si vous n'avez pas besoin d'un constructeur principal ;-)



2
votes

L'approche proposée dans la réponse de @ Januson est très agréable et propre lorsque vous ne définissez pas / définiriez un constructeur principal dans la sous-classe B . Si vous essayez de le faire, vous obtenez des erreurs de compilation, car les constructeurs auxiliaires doivent appeler le constructeur principal et ne peuvent pas appeler directement les constructeurs de superclasse.

Si vous B sous-classe avez besoin de définir un constructeur principal, vous peut aborder le problème en définissant la valeur par défaut comme une constante dans l ' objet compagnon de A et l'utiliser à la fois dans A et Constructeurs principaux de B , comme suit:

open class A(val x: Int = DefaultX) {
    companion object {
        val DefaultX:Int = 238;
    }
}

class B(y: Int, x: Int = DefaultX) : A(x)

De cette façon, vous définissez l'équivalent d'une variable Java static final , portée à A.

Vous devriez vous référer à la constante de la superclasse ' A.DefaultX dans la sous-classe B , mais vous ne le faites pas' t besoin de dupliquer sa valeur à la fois dans la classe A et dans la classe B...


2 commentaires

Pietro Martinelli depuis que j'ai plusieurs couches d'héritage définissant la valeur par défaut en tant que méthode ou champ compagnon rendent mon code plus propre mais en termes de performances, je pense que la solution de @ Januson est un peu plus efficace (ce n'est pas grand-chose dans les deux cas: D) de toute façon pour celui-ci je je vais pour plus propre


@PietroMartinelli Je vous serai reconnaissant d'avoir votre avis sur ma réponse.



0
votes

Dans votre situation, quelque chose comme ça peut vous aider!

val y = 0
val b = if (y == 0) B(y) else B(y, 0)

class B(y: Int, x: Int) : A() {
    constructor(y: Int) : this(y, if (y == 0) 238 else 0)
}

open class A(x: Int = 238)


1 commentaires

@Januson Je vous serai reconnaissant d'avoir votre avis.