Kotlin - Почему значения параметров должны передаваться в подклассах? - PullRequest
0 голосов
/ 27 января 2019

Мой код:

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

class FemaleClub(): Club()

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

Почему вышеуказанный код невозможен?

Почему он имеет ошибку

значение не передано для имени параметра

и

значение не передано длястрана параметров

в моем подклассе?Значения устанавливаются, когда я начинаю femaleClub.

Ответы [ 5 ]

0 голосов
/ 27 января 2019

Вам необходимо вызвать конструктор (первичный / вторичный) из класса, от которого вы хотите наследовать.

Club имеет только один конструктор, основной конструктор. Он принимает две строки в качестве параметров. Club не имеет пустого конструктора.

Таким образом, он не может быть вызван как Club().

Я бы предложил два изменения.

1) Свойства name и country из Club свойств

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

2) Объявить параметры в первичном конструкторе FemaleClub

Поскольку вы хотите иметь возможность указывать значения для name и country при создании экземпляра FemaleClub, было бы неплохо дать первичный конструктор FemaleClub name и country в качестве параметров. .

Кроме того, я бы порекомендовал использовать именованные параметры при передаче значений, так как вы можете легко смешать две строки (в результате чего передается имя в качестве страны и страна в качестве имени.

class FemaleClub(name: String, country: String): Club(name = name, country = country)
0 голосов
/ 27 января 2019

О классах Kotlin и наследовании читайте здесь Classes and Inheritance и здесь Kotlin Inheritance .

Вы можете использовать как минимум четыре подхода, чтобы получить то, что вы хотите:

Первый подход (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

Второй подход (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

Третий подход (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

Четвертый подход (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
0 голосов
/ 27 января 2019

В FemaleClub вы не указываете, что должно быть передано Club в качестве 2 String аргументов, name и country.

И вы нигде не указываете, что FemaleClub принимает 2 строки в качестве аргументов конструктора, поэтому последняя строка также не будет работать.

0 голосов
/ 27 января 2019

В вашем примере родительский класс Club имеет первичный конструктор , который, согласно спецификации языка, должен вызываться либо из вторичных конструкторов того же класса, либо первичного конструктора подклассов для инициализации параметров, определенных в первичном конструкторе .Если вы не хотите вызывать основной конструктор родительского класса из подклассов, у вас есть несколько вариантов:

  1. Установить значения по умолчанию для параметров первичный конструктор :

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

    В этом случае вы не сможете вызвать первичный конструктор с параметрами:

    // this is not possible
    var femaleClub = FemaleClub("Blue", "Australia")
    
  2. Создать вторичный конструктор в родительском классе, который вызывает первичный конструктор :

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

    Но также вы не сможете вызвать FemaleClub("Blue", "Australia").

Чтобы иметь возможность вызывать конструктор с параметрами подкласса FemaleClub("Blue", "Australia"), вам необходимо явно определить их в первичном конструкторе подкласса и вызвать первичный конструктор родителя, то есть:

class FemaleClub(name: String, country: String): Club(name, country) {}
0 голосов
/ 27 января 2019

Есть некоторые проблемы с вашим кодом:

  • FemaleClub не имеет конструктора, который принимает два аргумента, даже если базовый класс имеет один.

  • Первичный конструктор унаследованного класса должен вызывать первичный конструктор базового класса.Поскольку ваш базовый класс принимает два необнуляемых аргумента, вы должны предоставить их ему, иначе ваш код не будет компилироваться.

Эти проблемы можно исправить следующим образом:

class FemaleClub(name: String, country: String): Club(name, country) {
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...