2010-05-18 11 views
14

He creado un protocolo que mis clases necesitan para implementar y, a continuación, un factor fuera cierta funcionalidad común en una clase base, por lo que hizo esto:Cómo evitar la advertencia "aplicación incompleta" en la clase base parcial

@protocol MyProtocol 
- (void) foo; 
- (void) bar; 
@end 

@interface Base <MyProtocol> 
@end 

@interface Derived_1 : Base 
@end 

@interface Derived_2 : Base 
@end 

@implementation Base 
- (void) foo{ 
//something foo 
} 
@end 

@implementation Derived_1 
- (void) bar{ 
//something bar 1 
} 
@end 

@implementation Derived_2 
- (void) bar{ 
//something bar 2 
} 
@end 

De esta forma, en mi código uso una identificación genérica <MyProtocol>.

Las obras de código (siempre que la base no se utiliza directamente), pero el compilador ahoga al final de la aplicación de base con una advertencia:

Incomplete implementation of class Base

¿Hay una manera de evitar esta advertencia o, aún mejor, ¿es una forma más adecuada de obtener este comportamiento de clase base abstracta parcialmente implementado en Objc?

Respuesta

12

Usted posiblemente podría hacer algo como esto:

@implementation Base 

- (void)bar 
{ 
    if ([self class] == [Base class]) { 
     [self doesNotRecognizeSelector:_cmd]; 
    } 
} 

@end 

De esta manera, usted tiene una implementación, pero por defecto genera una excepción. Sin embargo, si una clase derivada llama accidentalmente [super bar] o no anula bar, entonces la excepción no se generará. Si eso no es lo que quiere, sólo podría acortarlo a:

@implementation Base 

- (void)bar 
{ 
    [self doesNotRecognizeSelector:_cmd]; 
} 

@end 

En cuyo caso, se produce una excepción, incluso si una subclase llama [super bar] o no anula bar.

+0

bien, esto al menos impondrá la implementación en las clases más derivadas. Sería bueno tener una advertencia de tiempo de compilación para methos no implementados, sin embargo, pero supongo que no hay manera (?) ¿Hay una forma correcta de hacer esta implementación parcial de la clase Base en Obj-c? – garph0

+0

No realmente. Como otros han notado, Objective-C no tiene clases base abstractas. Cada enfoque que alguna vez utilicé para emularlos solo te lleva a un lugar intermedio. – mipadi

9

En su definición de protocolo, debe declarar sus métodos bajo la palabra clave @optional.

El código debería tener este aspecto:

@protocol MyProtocol 

@optional 
- (void) foo; 
- (void) bar; 

@end 

ver este question el SO.

+0

Will not @optional hacer que la implementación del método opcional también en las clases derivadas? Quiero que la clase más derivada se vea forzada a implementar los métodos no implementados en la clase base ("barra", en este caso). – garph0

+0

@ garph0, No puedes elegir en Obj-C. –

1

En Obj-C, no hay concepto de clase abstracta. Entonces, no puedes dejar que tu clase base sea abstracta (lo que significa que no implementa todos los métodos en el protocolo). Solo puedes tener 2 opciones. Deje que el método en el protocolo sea optionol y luego lo implemente usted mismo en la clase derivada. O bien, obligar a todas las clases en la jerarquía de ponerlo en práctica, pero dejar que la persona que llama a tener cuidado de no llamar a las incorrectas los métodos

0

hago algo como esto

@protocol MyProtocol 
- (void) foo; 
- (void) bar; 
@end 

@interface BaseAbstract 
- (void) bar; // give a default implementation 
@end 

@interface Derived_1 : BaseAbstract<MyProtocol> 
// you will get a compiler warning for foo() since it is not implemented 

// you will NOT get compiler for bar() warning since a default 
// implementation is inherited 
@end 

@interface Derived_2 : BaseAbstract<MyProtocol> 
@end 

typedef BaseAbstract<MyProtocol> Base; 
Cuestiones relacionadas