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.

Другие вопросы по тегам