2016-07-14 69 views
7

Sto imparando veloce. Voglio sovrascrivere la funzione generica nella classe generica.Come sovrascrivere il metodo generico nella classe generica in swift?

Quando scrivo la parola chiave override, si verifica un errore di compilazione.

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

posso omettere override parola chiave. Ma quando dichiaro il tipo di oggetto come "Genitore", viene chiamato il metodo del genitore (non il metodo figlio). Non è "override" letteralmente.

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 questo esempio, voglio ottenere "bambino" come risultato di object.genericFunc(1). (In altre parole, voglio "ignorare" il metodo.)

Come posso ottenere questo? Ci sono soluzioni alternative per raggiungere questo obiettivo?

So che posso chiamare il metodo figlio mediante il casting. Ma nella vera app che sto sviluppando, non posso sapere il tipo di cast perché voglio renderlo polimorfico.

Ho letto anche Overriding generic function error in swift post, ma non ho potuto risolvere questo problema.

Grazie!

+0

Dire 'object' è un' GenericParent 'sta solo dicendo al compilatore quali metodi e proprietà sono disponibili. Non cambia la classe da 'AbsoluteChild' a' GenericParent '. 'GenericParent ' rende disponibile il metodo 'genericFunc', ma' object' è ancora un 'AbsoluteChild'; il che significa che quando chiami 'genericFunc', chiamerà l'implementazione del bambino. Non è possibile eseguire il cast dell'oggetto sulla sua classe genitore per ottenere l'implementazione del genitore. – keithbhunter

+0

Grazie! Ma quando eseguo il secondo campione al campo da giuoco, 'object.genericFunc (1)' stampa "genitore". Significa che viene chiamata l'implementazione dei genitori. Come posso capire questo? –

+0

Oh, lo vedo anch'io. Sembra un insetto. Puoi inviarlo come bug a [bugreport.apple.com] (https://bugreport.apple.com) o alla pagina [Swift GitHub] (https://github.com/apple) – keithbhunter

risposta

0

Dichiarando object come GenericParent<Int>, è possibile convertirlo in un'istanza della superclasse.

Si potrebbe considerare l'utilizzo di un protocollo anziché di una superclasse generica se non si sa ancora esattamente quale sarà il tipo in fase di esecuzione. In un protocollo puoi definire i requisiti dell'oggetto che ti aspetti.

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" 

Se hai ancora bisogno di un'implementazione di default, come si farebbe nella vostra GenericParent superclasse originale, è possibile farlo in un protocollo di estensione in questo modo:

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

Alla fine stampa "strumento predefinito"? Per quanto ne capisco, vuole un "buongiorno" a quel punto. – jboi

+0

Nella prima parte del codice stampa "ciao mondo". La seconda parte che ho aggiunto nel caso avesse bisogno anche di un'implementazione di default come avrebbe fatto nella sua superclasse generica. – Juul