Swift, могу ли я переопределить метод с более конкретным типом производного параметра
Игральная карта наследуется от Карты
Даны две функции с одинаковым именем:
func match(othercards : [PlayingCard]) -> Int {
return 2
}
func match(othercards : [Card]) -> Int {
return 2
}
Он выбрасывает сообщение "Ошибка: метод переопределения с селектором" соответствует: "имеет несовместимый тип" ([PlayingCard]) -> Int'
Зачем??? Его две функции с одинаковыми именами, но с двумя разными параметрами, почему он все еще запрашивает переопределение?? Если я это сделаю, то даже это называется ошибкой
3 ответа
Так как PlaingCard наследует от Card, вы не можете переопределить метод таким способом.
Подумайте, что произойдет, если вы попытаетесь вызвать совпадение с экземпляром PlayingCard. Какой из двух методов это вызовет? Это было бы неоднозначно и поэтому не допускается.
В этом случае одним из решений является изменение имени метода, который принимает более конкретный тип. например
func matchPlayingCard(othercards : [PlayingCard]) -> Int {
return 2
}
Ты можешь сделать это?
class Card {
func match(othercards : [Card]) -> Int {
return 2 // I changed the return value just to test it
}
}
class PlayingCard : Card {
func match(othercards : [PlayingCard]) -> Int {
return 1
}
}
Да!
В частности, вы можете, если карта не расширяет NSObject.
class Card {
func match(othercards : [Card]) -> Int {
return 2 // I changed the return value just to test it
}
}
С другой стороны, если Card
продолжается NSObject
,
class Card : NSObject {
func match(othercards : [Card]) -> Int {
return 2 // I changed the return value just to test it
}
}
Тогда вы получите ошибку!
Это выглядит как overloading
работает только на "чистых" классах Swift.
Компилятор Swift должен видеть оба PlayingCard
а также Card
как того же типа. Если кто-то наследует (либо по подтипу, либо по протоколу (при определенных обстоятельствах)), это может объяснить это.
Хотя это может рассматриваться как запах кода, вы также можете проверить тип во время выполнения и использовать только одну функцию, как в принятом здесь ответе: Проверка, является ли объект заданным типом в Swift.
Некоторые шаблоны, которые могут быть применены, приведены в этом объяснении аналогичного примера - хотя вопрос касается C#, могут применяться аналогичные объектно-ориентированные методы: переопределение метода с производным параметром вместо base.