2011-12-15 20 views
5

Tengo experiencia con la programación orientada a objetos; sin embargo, esta situación no me resulta familiar por algún motivo. Considere el siguiente Objective-C 2.0 código:Método de llamada en la clase hija desde el método de la clase padre (Objective-c 2.0)

@interface A : NSObject 
@end 

@implementation A 
- (void) f { 
    [self g]; 
} 
@end 

@interface B : A 
@end 

@implementation B 
- (void) g { 
    NSLog(@"called g..."); 
} 
@end 

¿Es esta la forma correcta de llamar a un método en una clase hija de un método de la clase padre? ¿Qué sucede si otra clase secundaria no implementa el método g? Quizás haya una mejor manera de resolver esto como un método abstracto en la clase principal A?

+1

posible duplicado de [está enviando el mensaje a hijo de padres] (http://stackoverflow.com/questions/3351937/sending-message-to -child-parent-parent) –

+1

Ver también: [método de la subclase de llamada de su superclase] (http://stackoverflow.com/questions/7515582/call-subclasss-method-from-its-superclass) –

Respuesta

11

La clave es tener un método en la clase principal que se puede anular en la clase secundaria.

@interface Dog : NSObject 
- (void) bark; 
@end 

@implementation Dog 
- (void) bark { 
    NSLog(@"Ruff!"); 
} 
@end 

@interface Chihuahua : Dog 
@end 

@implementation Chihuahua 
- (void) bark { 
    NSLog(@"Yipe! Yipe! Yipe!"); 
} 
@end 

Verá, su clase secundaria anulará el método principal con su propia implementación. Es posible que vea que utiliza como esto:

Dog *someDog = [Chihuahua alloc] init] autorelease]; 
[someDog bark]; 

Salida: Yipe! Yipe! Yipe!

+0

Tiene sentido. ¿Es necesario declarar 'ladrido' en la interfaz de la clase padre? – SundayMonday

+1

'ladrido' debe declararse en su interfaz. Sí. – Jeremy

+1

Puede haber una situación diferente en la que realmente desee llamar a un método diferente, como lo que ha descrito. Por ejemplo, es posible que desee utilizar un patrón de plantilla: [patrón de método de plantilla] (http://en.wikipedia.org/wiki/Template_method_pattern), como si desea llamar a 'ladrido' como en mi ejemplo, sin embargo, ladrar entonces, a su vez, llamaría a algunos métodos internos que luego se anularán por clase secundaria, al igual que el ejemplo de Squeegy. – Jeremy

3

Debe implementar g en la clase principal, pero no hacer nada. De esta manera se puede llamar sin error, pero aún se puede anular.

@interface A : NSObject 
@end 

@implementation A 
- (void) f { 
    [self g]; 
} 
- (void) g {} // Does nothing in baseclass 
@end 

@interface B : A 
@end 

@implementation B 
- (void) g { 
    NSLog(@"called g..."); 
} 
@end 

O comprueba el método en el objeto antes de ejecutarlo.

if ([self respondsToSelector:@selector(g)]) { 
    [self performSelector:@selector(g) withObject:nil]; 
} 

Pero eso puede ponerse bastante feo.

+0

El compilador activa las advertencias sin embargo, ¿no? Dado que la compilación cree que sabe que la clase de 'self' no implementa ese método? –

Cuestiones relacionadas