2011-09-22 15 views
10

Ho due classi, denominate Parent e Child, come di seguito. Parent è la superclasse di Child Posso chiamare un metodo della superclasse dalla sottoclasse utilizzando la parola chiave super. È possibile chiamare un metodo di sottoclasse dalla sua superclasse?Chiamare il metodo della sottoclasse dalla sua superclasse

Child.h

#import <Foundation/Foundation.h> 
#import "Parent.h" 

@interface Child : Parent { 

} 

- (void) methodOfChild; 

@end 

Child.m

#import "Child.h" 

@implementation Child 

- (void) methodOfChild { 

    NSLog(@"I'm child"); 

} 

@end 

Parent.h:

#import <Foundation/Foundation.h> 

@interface Parent : NSObject { 

} 

- (void) methodOfParent; 

@end 

Parent.m:

#import "Parent.h" 

@implementation Parent 

- (void) methodOfParent { 

    //How to call Child's methodOfChild here? 

} 

@end 

Importa "Parent.h" in intestazione del file .m applicazione del delegato.

il metodo di App delegato application:didFinishLaunchingWithOptions: ..

Parent *parent = [ [Parent alloc] init]; 

[parent methodOfParent]; 

[parent release]; 
+7

Sì, è tecnicamente possibile ma questo design ha un cattivo odore. Davvero pessimo. Le superclassi non dovrebbero conoscere le loro sottoclassi. –

+0

Voglio raggiungere lo stesso quando chiamato da swift, swift in grado di riconoscere i metodi in tale gerarchia. Qualcuno può dire come ottenere lo stesso quando la prima chiamata viene inizializzata da una classe veloce? – NaXir

risposta

58

È possibile, come metodo di Objective C la spedizione è tutto dinamico. Chiamalo semplicemente con [self methodOfChild], che probabilmente genererà un avviso del compilatore (che puoi silenziare rilasciando self a id).

Ma, per amore del bene, non farlo. I genitori dovrebbero provvedere ai loro figli, non i bambini per i loro genitori. Un genitore che conosce i nuovi metodi di una sottoclassi è un enorme problema di progettazione, creando un forte accoppiamento nel modo sbagliato nella catena di ereditarietà. Se il genitore ne ha bisogno, perché non è un metodo sul genitore?

+1

Risposta fantasticamente scritta e corretta. Complimenti! – sosborn

+7

Forse il poster di origine sta pensando in termini di una classe base astratta in stile C++ (cioè, che definisce i metodi ma non fornisce implementazioni), e il consiglio corretto è quello di fornire implementazioni vuote sul genitore, lasciando che un bambino esegua l'override loro se e solo se è rilevante? – Tommy

+0

Grazie per le tue fantastiche informazioni .. – Confused

2

super significa "invoca un metodo di invio sulla classe padre", quindi è possibile utilizzare super nella sottoclasse perché una sottoclasse ha solo una classe genitore. Una classe può avere molte _sub_classes, quindi come faresti a sapere quale implementazione del metodo chiamare, nel caso generale? (Quindi non esiste una parola chiave sub.)

Tuttavia, nel tuo esempio hai due metodi separati. Non c'è nulla ti impedisce (ammesso che abbiate ottimi motivi per fare qualcosa di simile!) Dal dire, nel genitore,

- (void) methodOfParent { 
    [self methodOfChild]; 
} 
+2

È utile indicare _why_ una risposta non corretta. Come succede, il mio non lo è: obj-c invia dinamicamente, 'super' significa" eseguire la ricerca del metodo a partire dal dizionario dei metodi di mio padre ", e tu potresti avere una buona ragione per fare qualcosa che altrimenti sembra orribile. –

6

Tecnicamente si può fare. Ma ti suggerisco di modificare il tuo design. È possibile dichiarare un protocollo e fare in modo che la classe figlio adotti tale protocollo. Quindi è possibile verificare se il bambino adotta tale protocollo dalla super classe e chiamare il metodo dalla super classe.

+0

Grazie per le vostre informazioni .. – Confused

+1

Potete fornire/condividere qualche codice di esempio per farlo con i protocolli? – Confused

5

È possibile utilizzare questo:

Parent.m

#import "Parent.h" 

@implementation Parent 

- (void) methodOfChild { 

    // this should be override by child classes 
    NSAssert(NO, @"This is an abstract method and should be overridden");  
} 

@end 

Il genitore sa circa il bambino e il bambino ha una scelta su come implementare la funzione.

0

se il super-ha più subs poi andare per questo uno per il metodo della specifica del sub

if ([super isKindOfClass:[specificsub class]]) { 
       [specificsub methodName]; 
      } 

se il super-a che fare con l'oggetto (che sotto) in modo sub del metodo l'accesso verrà chiamato in altro modo è in super classe

super *some = [[sub alloc] init]; 
[some methodName]; 
0

Questo può essere fatto superando il metodo nella sottoclasse. Quello è creare un metodo nella classe genitore e superare la stessa in sottoclasse.