Implementar un método virtual puro en Objective-C


Quiero ir allí. Sin embargo, en serio, ¿cómo se implementa un método virtual puro de una manera "Apple"? ¿Usas un Protocolo con tu clase base y lanzas excepciones en esos métodos?

Author: Kara, 2011-03-07

6 answers

Cuando programasen Objective-C necesitas purgar tu mente de cosas tales como métodos virtuales. No llamas a métodos en objetos Objective-C, les envías mensajes. Los objetos responden a los mensajes o no, pero debido al enlace dinámico, no se puede decir esto hasta el tiempo de ejecución.

Por lo tanto, puede declarar un método en un objeto base y no no proporcionar una implementación, no hay problema (excepto por la advertencia del compilador), pero no puede tener el indicador del compilador cuando instanciar un objeto con tales métodos y no lanzará un error en tiempo de ejecución a menos que realmente envíe ese mensaje al objeto.

La mejor manera de crear clases base "virtuales" (en mi opinión) es declarar el método y darle una implementación de stub que arroje una excepción adecuada.

 55
Author: JeremyP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-07 20:09:44

En Objective-C, no hay soporte virtual puro como en C++.

Una simulación sería que declare un método en su interfaz pero no lo implemente en su .archivo m. Por supuesto que obtendrías advertencias del compilador, pero IIRC puedes desactivarlas. Pero no obtendrá advertencias / errores si no los sobrescribe en la subclase, que se obtiene en C++ (IIRC).

Una alternativa sería implementarlos con solo un cuerpo NSAssert(NO, @"Subclasses need to overwrite this method");. Aún así, solo lo cogerías en tiempo de ejecución, no en tiempo de compilación.

 32
Author: DarkDust,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-07 16:28:18

Dependiendo de lo que esté haciendo, el patrón de delegado puede ser más apropiado que una subclase, donde el delegado se define como id<YourDelegateProtocol>. El compilador generará una advertencia si no se implementan los métodos requeridos en el protocolo delegado.

La subclase generalmente se evita en Objective-C ya que los objetos no pueden heredar de múltiples superclases, pero pueden implementar múltiples protocolos.

 7
Author: Matt Stevens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-07 18:18:00

Debes usar:

- (void)doesNotRecognizeSelector:(SEL)aSelector method. 

Como señaló Apple, aquí: https://developer.apple.com/library/mac/#documentation/cocoa/reference/Foundation/Classes/NSObject_Class/Reference/Reference.html

 6
Author: Antony Clements,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-21 11:19:53

Tienes algunas opciones, pero estás en el camino correcto.

ObjC no soporta esto directamente, forzar a las subclases a implementar un protocolo es la mejor manera de comprobarlo en la compilación.

Implementar'Secretamente' el método en la clase base y asertar es lo que hago para confirmar que el subclase ha subclasado correctamente en tiempo de ejecución. Algunas personas tienen sentimientos encontrados sobre las afirmaciones, o deben dejarlas activas, por lo que no siempre es una buena solución.

También puedes forzar las subclases usan un constructor de clase específico y una secuencia de inicialización, luego verifican que han implementado todo lo necesario antes de devolver una instancia, en caso de que las advertencias del compilador no lo corten.

Pero a ObjC le faltan algunas características de lang que permiten a los clientes dispararse a sí mismos en el pie, o solucionar lo que deseen... no deberías quedarte demasiado atascado en su cumplimiento.

Nota: Las excepciones son muy poco comunes (y un poco inseguras, también) en ObjC.

 2
Author: justin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-07 16:40:32

Un método virtual es un método cuyo comportamiento puede ser anulado dentro de una clase heredera por una función con la misma firma (es decir, el mismo nombre con el mismo número de parámetros y tipo de parámetros).

Ejemplo:-

@implementation BaseClass

-(void)viewDidLoad
{
 [self virtualMethod:123];
}

-(void)virtualMethod:(int)param
{
 //implement this method in subclass
}

@end

////////////////////////////////////////////////////

@interface ChildClass:BaseClass
@end

@implementation ChildClass

-(void)virtualMethod:(int)param
{
 NSLog(@"There is no keyword "Virtual" in Objective C.");
}
@end

Producto:-

" No hay ninguna palabra clave "Virtual" en el Objetivo C. "

 0
Author: Deepak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-12 09:18:38