2016-07-14 1 views
7

Я учусь быстро. Я хочу переопределить общую функцию в родовом классе.Как переопределить общий метод в родовом классе в swift?

Когда я пишу override ключевое слово, происходит ошибка компиляции.

class GenericParent<U> { 
    func genericFunc<T>(param: T) { print("parent") } 
} 

class AbsoluteChild: GenericParent<Int> { 
    override func genericFunc<T>(param: T) { print("child") } 
    // ! Method does not override any method from its superclass (compile error) 
} 

Я могу опустить override ключевое слово. Но когда я объявляю тип объекта как «Родительский», вызывается метод parent (а не дочерний метод). Это не «переопределение» буквально.

class GenericParent<U> { 
    func genericFunc<T>(param: T) { print("parent") } 
} 

class AbsoluteChild: GenericParent<Int> { 
    func genericFunc<T>(param: T) { print("child") } 
} 

var object: GenericParent<Int> 
object = AbsoluteChild() 
object.genericFunc(1) // print "parent" not "child" 

// I can call child's method by casting, but in my developing app, I can't know the type to cast. 
(object as! AbsoluteChild).genericFunc(1) // print "child" 

В этом примере я хочу получить «ребенка» в результате object.genericFunc(1). (Другими словами, я хочу «переопределить» метод.)

Как я могу это получить? Есть ли обходные пути для достижения этого?

Я знаю, что могу назвать метод ребенка методом литья. Но в фактическом приложении, которое я разрабатываю, я не могу знать, какой тип следует использовать, потому что я хочу сделать его полиморфным.

Я также прочитал сообщение Overriding generic function error in swift, но я не мог решить эту проблему.

Спасибо!

+0

Говоря 'object' является' GenericParent 'только сообщает компилятору, какие методы и свойства доступны. Он не изменяет класс от 'AbsoluteChild' до' GenericParent '. 'GenericParent ' делает метод 'genericFunc' доступным, но' object' по-прежнему является 'AbsoluteChild'; что означает, что когда вы вызываете 'genericFunc', он будет вызывать реализацию ребенка. Вы не можете отнести объект к его родительскому классу, чтобы получить реализацию родителя. – keithbhunter

+0

Спасибо! Но когда я выполняю второй образец на игровой площадке, 'object.genericFunc (1)' печатает "родителя". Это означает, что выполняется реализация родителя. Как я могу это понять? –

+0

О, я тоже это вижу. Это похоже на ошибку. Вы можете отправить его как ошибку в [bugreport.apple.com] (https://bugreport.apple.com) или на страницу [Swift GitHub] (https://github.com/apple) – keithbhunter

ответ

0

Объявив object, как GenericParent<Int>, вы добавили его в качестве экземпляра суперкласса.

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

protocol MyObjectType { 
    func genericFunc<T>(param: T) ->() 
} 

class AbsoluteChild: MyObjectType { 
    func genericFunc<T>(param: T) { 
     print("hello world") 
    } 
} 

var object: MyObjectType 
object = AbsoluteChild() 
object.genericFunc(1)// prints "hello world" 

Если вам все еще нужна реализация по умолчанию, как вы могли бы сделать в оригинальном суперкласса GenericParent, вы можете сделать это в расширении протокола, как так:

extension MyObjectType { 
    func genericFunc<T>(param: T) { 
    print("default implementation") 
    } 
} 

class AnotherObject: MyObjectType { 
    //... 
} 

var object2: MyObjectType 
object2 = AnotherObject() 
object2.genericFunc(1)// prints "default implementation" 
+0

Действительно ли он печатает «по умолчанию» в конце? Насколько я понимаю, в этот момент ему нужен «мир привет». – jboi

+0

В первой части кода он печатает «hello world». Вторая часть, которую я добавил, в случае, если он также нуждается в реализации по умолчанию, как он сделал бы в своем универсальном суперклассе. – Juul