Mon code:

open class Club(name: String, country: String)

class FemaleClub(): Club()

var femaleClub = FemaleClub("Blue", "Australia")

Pourquoi le code ci-dessus n'est-il pas possible?

Pourquoi a-t-il l'erreur

aucune valeur passée pour le nom du paramètre

Et

aucune valeur transmise pour le paramètre pays

Dans ma sous-classe? Les valeurs sont définies lorsque je lance femaleClub.

0
Zorgan 27 janv. 2019 à 03:29

5 réponses

Meilleure réponse

Dans votre exemple, la classe parente Club a un constructeur principal qui, par spécification du langage, doit être appelé à partir de constructeurs secondaires de la même classe ou de primaire constructeur de sous-classes pour initialiser les paramètres définis dans le constructeur principal . Si vous ne souhaitez pas appeler un constructeur principal d'une classe parente à partir de sous-classes, vous avez deux options:

  1. Définissez les valeurs par défaut sur les paramètres du constructeur principal :

    open class Club(name: String = "DefaultName", country: String = "Country") {
    }
    

    Dans ce cas, vous ne pourrez pas appeler le constructeur principal avec les paramètres:

    // this is not possible
    var femaleClub = FemaleClub("Blue", "Australia")
    
  2. Créez un constructeur secondaire dans la classe parent qui appelle le constructeur principal :

    open class Club(name: String, country: String) {
    
        constructor(): this("Name", "Country")
    }
    

    Mais vous ne pourrez pas non plus appeler FemaleClub("Blue", "Australia").

Pour pouvoir appeler le constructeur avec les paramètres d'une sous-classe FemaleClub("Blue", "Australia"), vous devez les définir explicitement dans le constructeur principal de la sous-classe et appeler le constructeur principal du parent, c'est-à-dire:

class FemaleClub(name: String, country: String): Club(name, country) {}
2
Sergey 27 janv. 2019 à 07:45

Vous devez appeler le constructeur (primaire / secondaire) de la classe dont vous souhaitez hériter.

Club n'a qu'un seul constructeur, le constructeur principal. Il prend deux chaînes comme paramètres. Club n'a pas de constructeur vide.

Donc, il ne peut pas être appelé en tant que Club().

Je proposerais deux changements.

1) Faire name et country de Club propriétés

open class Club(name: String, country: String)

2) Déclarer les paramètres dans le constructeur principal de FemaleClub

Puisque vous souhaitez pouvoir spécifier des valeurs pour name et country lorsque vous instanciez FemaleClub, il serait judicieux de donner le constructeur principal de FemaleClub {{X4} } et country comme paramètres.

De plus, je recommanderais d'utiliser des paramètres nommés lors de la transmission des valeurs, car vous pouvez facilement mélanger les deux chaînes (résultant en passant le nom en tant que pays et le pays en tant que nom.

class FemaleClub(name: String, country: String): Club(name = name, country = country)
0
Willi Mentzel 27 janv. 2019 à 15:06

Dans FemaleClub, vous ne spécifiez pas ce qui doit être passé à Club comme ses 2 String arguments, name et country.

Et vous ne spécifiez nulle part que FemaleClub prend 2 chaînes comme arguments de constructeur, donc la dernière ligne ne fonctionnera pas non plus.

0
jbx 27 janv. 2019 à 00:48

À propos des classes et de l'héritage Kotlin, lisez ici Classes and Inheritance et ici Kotlin Inheritance.

Vous pouvez utiliser au moins quatre approches pour obtenir ce que vous voulez:

Première approche (default values):

open class Club(var name: String = "Blue", var country: String = "Australia") {  }

public class FemaleClub(): Club() {  }

fun main() { 
    var femaleClub = FemaleClub()
    println("RESULT: ${femaleClub.country}")
}

// RESULT: Australia

Deuxième approche (passing values):

open class Club(var name: String, var country: String) {  }

class FemaleClub(): Club("Green", "NZ") {  }

fun main() {
    var femaleClub = FemaleClub()
    println("RESULT: ${femaleClub.country}")
}

// RESULT: NZ

Troisième approche (init block):

open class Club(name: String, country: String) {  

    var name: String = "Blue"
    var country: String = "Australia"

    init {
        this.name = name
        this.country = country 
    }
}

class FemaleClub(): Club("Green", "NZ") {  }

fun main() {
    var femaleClub = FemaleClub()
    println("RESULT: ${femaleClub.country}")
}

// RESULT: NZ

Quatrième approche (class sec.constructor):

open class Club {  

    var name: String
    var country: String

    constructor(name: String = "Blue", country: String = "Australia") {
        this.name = name
        this.country = country
    }
}

class FemaleClub(): Club() {  }

fun main() {
    var femaleClub = FemaleClub()
    println("RESULT: ${femaleClub.country}")
}

// RESULT: Australia
1
Willi Mentzel 27 janv. 2019 à 14:56

Il y a quelques problèmes avec votre code:

  • FemaleClub n'a pas de constructeur qui accepte deux arguments, même si la classe de base en a un.

  • Le constructeur principal de la classe héritée doit appeler le constructeur principal de la classe de base. Étant donné que votre classe de base accepte deux arguments non nullables, vous devez les lui fournir, sinon votre code ne sera pas compilé.

Ces problèmes peuvent être résolus de la manière suivante:

class FemaleClub(name: String, country: String): Club(name, country) {
}
1
Ervin Szilagyi 27 janv. 2019 à 00:47