2011-09-22 9 views
10

Tengo dos clases, llamadas Parent y Child, como a continuación. Parent es la superclase de Child Puedo llamar a un método de la superclase desde su subclase usando la palabra clave super. ¿Es posible llamar a un método de subclase desde su superclase?Método de la subclase de llamada de su superclase

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 

importación "Parent.h" en el encabezado del archivo .m aplicación del delegado.

método de aplicación delegado application:didFinishLaunchingWithOptions: ..

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

[parent methodOfParent]; 

[parent release]; 
+7

Sí, es técnicamente posible, pero este diseño huele. Muy mal. Se supone que las superclases no deben saber sobre sus subclases. –

+0

Quiero lograr lo mismo cuando se llama desde rápido, rápido en no poder reconocer los métodos en dicha jerarquía. ¿Alguien puede decir cómo lograr lo mismo cuando se inicializa la primera llamada de una clase rápida? – NaXir

Respuesta

58

Usted puede, Objetivo de despacho método C es todo dinámico. Simplemente llámelo con [self methodOfChild], que probablemente genere una advertencia del compilador (que puede silenciar al enviar self a).

Pero, por el amor de la bondad, no lo hagas. Se supone que los padres deben proveer a sus hijos, no a los hijos por sus padres. Un padre que conozca las nuevas clases de subclases es un gran problema de diseño, ya que crea un acoplamiento fuerte en el camino equivocado de la cadena de herencia. Si el padre lo necesita, ¿por qué no es un método en el padre?

+1

Escrito fantásticamente y respuesta correcta. ¡Prestigio! – sosborn

+7

Posiblemente el póster de origen está pensando en términos de una clase base abstracta de estilo C++ (es decir, una que define métodos pero no proporciona implementaciones), y el consejo correcto es proporcionar implementaciones vacías en el padre, dejando que un hijo anule ellos si y solo si es relevante? – Tommy

+0

Gracias por su gran información .. – Confused

2

super significa "invocar un método de envío en la clase principal", por lo que puede usar super en la subclase porque una subclase solo tiene una clase principal. Sin embargo, una clase puede tener muchas _sub_classes, entonces, ¿cómo sabría qué implementación de método llamar, en el caso general? (Por lo tanto, no existe una palabra clave sub).

Sin embargo, en su ejemplo, tiene dos métodos separados. No hay nada que nos impida (suponiendo que tiene muy buenas razones para hacer algo como esto!) De decir, en el padre,

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

Es útil indicar _por qué_ una respuesta es incorrecta. Da la casualidad, la mía no: Obj-c despacha dinámicamente, 'super' significa" realizar la búsqueda de métodos comenzando con el diccionario de métodos de mis padres ", y tienes una buena razón para hacer algo que de otra manera parece horrible. –

6

Técnicamente puede hacerlo. Pero te sugiero que modifiques tu diseño. Puede declarar un protocolo y hacer que su clase hija adopte ese protocolo. Entonces puede tener que verificar si el niño adopta ese protocolo de la superclase y llamar al método de la superclase.

+0

Gracias por su información .. – Confused

+1

¿Podría proporcionar/compartir un código de muestra para hacerlo con protocolos? – Confused

5

Usted podría utilizar esto:

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 

El padre sabe sobre el niño y el niño tiene una opción sobre cómo implementar la función.

0

si su súper tiene varios submarinos luego ir por éste para el método específico de sub

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

si su súper está tratando con ese objeto (que sub) de modo secundario del método Registrado se llamará de otra manera está en usted super clase

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

Esto se puede hacer al utilizar el método en la subclase. Eso es crear un método en la clase primaria y montar el mismo en la subclase.

Cuestiones relacionadas