2016-07-14 16 views
7

Ich lerne schnell. Ich möchte generische Funktion in der generischen Klasse überschreiben.Wie überschreiben generische Methode in generische Klasse in Swift?

Wenn ich override Schlüsselwort schreibe, geschieht Kompilierungsfehler.

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) 
} 

Ich kann override Schlüsselwort weglassen. Aber wenn ich den Objekttyp als "Parent" deklariere, wird die Methode des Elterns aufgerufen (nicht die Child-Methode). Es ist nicht "überschreiben" buchstäblich.

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" 

In diesem Beispiel möchte ich „Kind“ als Folge der object.genericFunc(1) zu bekommen. (Mit anderen Worten, ich möchte die Methode "überschreiben".)

Wie kann ich das bekommen? Gibt es Workarounds, um dies zu erreichen?

Ich weiß, dass ich die Methode des Kindes durch Casting nennen kann. Aber in der eigentlichen App, die ich entwickle, kann ich nicht den Typ für die Besetzung wissen, weil ich es polymorph machen möchte.

Ich lese auch Overriding generic function error in swift Post, aber ich konnte dieses Problem nicht lösen.

Vielen Dank!

+0

sagen 'object' ist ein' GenericParent 'teilt dem Compiler nur mit, welche Methoden und Eigenschaften verfügbar sind. Es ändert nicht die Klasse von 'AbsoluteChild' nach' GenericParent '. 'GenericParent ' macht die 'genericFunc' Methode verfügbar, aber' object' ist immer noch eine 'AbsoluteChild'; Das heißt, wenn Sie 'genericFunc' aufrufen, wird die Implementierung des Kinds aufgerufen. Sie können das Objekt nicht in seine übergeordnete Klasse umwandeln, um die Implementierung des übergeordneten Elements abzurufen. – keithbhunter

+0

Danke! Aber wenn ich das zweite Beispiel auf dem Spielplatz ausführe, druckt 'object.genericFunc (1)' "Eltern". Es bedeutet, dass die Implementierung von Eltern aufgerufen wird. Wie kann ich das verstehen? –

+0

Oh, das sehe ich auch. Das scheint ein Fehler zu sein. Sie könnten es als Bug an [bugreport.apple.com] (https://bugreport.apple.com) oder an die [Swift GitHub-Seite] (https://github.com/apple) senden – keithbhunter

Antwort

0

Wenn Sie object als GenericParent<Int> deklarieren, wird es als Instanz der Oberklasse interpretiert.

Sie könnten ein Protokoll anstelle einer generischen Oberklasse verwenden, wenn Sie noch nicht genau wissen, was Ihr Typ zur Laufzeit sein wird. In einem Protokoll können Sie die Anforderungen des erwarteten Objekts definieren.

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" 

Wenn Sie noch eine Standardimplementierung benötigen, wie Sie in Ihrem ursprünglichen Super GenericParent tun würde, können Sie wie dies in einem Protokoll-Erweiterung tun, dass:

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

Drucken wirklich "Standard-Gerät" am Ende? Soweit ich die Frage verstehe, will er zu diesem Zeitpunkt eine "Hallo Welt". – jboi

+0

Im ersten Code-Teil wird "Hallo Welt" gedruckt. Der zweite Teil, den ich hinzugefügt habe, falls er auch eine Standardimplementierung benötigt, wie er es in seiner generischen Superklasse machen würde. – Juul

Verwandte Themen