498 votos

La creación de una clase abstracta en Objective C

Soy originalmente de un programador de Java que ahora trabaja con Objective-C. me gustaría crear una clase abstracta, pero que no parece ser posible en Objective-C. ¿Es esto posible?

Si no, ¿cómo cerca de una clase abstracta puedo conseguir en Objective-C?

625voto

Barry Wark Puntos 73462

Normalmente, la clase Objective-C son abstractas, por convención, sólo-si el autor de los documentos de una clase como abstracta, simplemente no lo uso sin crear subclases. No hay ninguna compilación en tiempo de ejecución que impide la creación de instancias de una clase abstracta, sin embargo. De hecho, no hay nada que impida que un usuario proporciona implementaciones de métodos abstractos a través de una categoría (es decir. en tiempo de ejecución). Usted puede forzar a un usuario a, al menos, reemplazar ciertos métodos elevando una excepción en los métodos de aplicación, en su resumen de la clase:

[NSException raise:NSInternalInconsistencyException 
            format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)];

Si el método devuelve un valor, es un poco más fácil de usar

@throw [NSException exceptionWithName:NSInternalInconsistencyException
                               reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
                             userInfo:nil];

como entonces no necesita añadir un retorno de la declaración del método.

Si la clase abstracta es realmente una interfaz (es decir. no tiene ningún método concreto para implementaciones), el uso de un Objetivo-C del protocolo es la opción más apropiada.

267voto

Grouchal Puntos 7053

No hay ninguna forma para crear una clase abstracta en Objective C.

Usted puede burlarse de una clase abstracta - en la elaboración de los métodos/ selectores de llamada doesNotRecognizeSelector: y por lo tanto elevar una excepción con lo que la clase inutilizable.

por ejemplo:

- (id)someMethod:(SomeObject*)blah
{
     [self doesNotRecognizeSelector:_cmd];
     return nil;
}

usted también puede hacer esto por init.

60voto

Yar Puntos 25421

Sólo riffs en @Barry Wark la respuesta de arriba (y la actualización de iOS 4.3) y dejar este para mi propia referencia:

#define mustOverride() @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"%s must be overridden in a subclass/category", __PRETTY_FUNCTION__] userInfo:nil]
#define methodNotImplemented() mustOverride()

a continuación, en sus métodos que usted puede utilizar este

- (void) someMethod {
     mustOverride(); // or methodNotImplemented(), same thing
}



Notas: No se si hacer una macro verse como una función de C es una buena idea o no, pero voy a seguir hasta que enseñan lo contrario. Creo que es más correcto usar NSInvalidArgumentException (en lugar de NSInternalInconsistencyException) ya que el sistema de tiempo de ejecución se produce en respuesta a doesNotRecognizeSelector ser llamado (véase NSObject docs).

41voto

redfood Puntos 402

Yo sé que esto fue preguntado/respondida hace mucho, pero la solución que se me ocurrió es:

  1. Crear un Protocolo para todo lo que usted desea en su "resumen" de la clase
  2. Crear una clase base (o tal vez llamar a lo abstracto) que implementa el protocolo. Para todos los métodos que desea "abstracto" de ponerlas en el archivo .m, pero no el archivo .h.
  3. Pídale a su niño de la clase hereda de la clase base Y aplicar el protocolo. De esta manera el compilador dará un mensaje de advertencia para cualquier método en el protocolo que no se implementado por su niño de la clase.

No es tan sucinta como en Java, pero usted consigue el deseado de advertencia del compilador.

34voto

Steve918 Puntos 863

de Omni Grupo de la lista de correo

Objective-C no tiene el resumen del compilador de construcción como en Java este tiempo.

Así que todo lo que hacemos es definir la clase abstracta como cualquier otra clase normal y aplicar los métodos de talonarios para los métodos abstractos que están vacío o informe de no-soporte para el selector. Por ejemplo...

- (id)someMethod:(SomeObject*)blah
{
     [self doesNotRecognizeSelector:_cmd];
     return nil;
}

También hago la siguiente para evitar la inicialización del resumen clase a través de la inicializador predeterminado.

- (id)init
{
     [self doesNotRecognizeSelector:_cmd];
     [self release];
     return nil;
}

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X