2010-11-16 18 views
85

Tengo 2 clases, una incluye methodA y la otra incluye methodB. Entonces, en una nueva clase, necesito anular los métodos methodA y methodB. Entonces, ¿cómo logro herencia múltiple en el objetivo C? Estoy un poco confundido con la sintaxis.Herencia múltiple de Objective-C

Respuesta

127

Objective-C no es compatible con herencia múltiple, y no lo necesita. Use la composición:

@interface ClassA : NSObject { 
} 

-(void)methodA; 

@end 

@interface ClassB : NSObject { 
} 

-(void)methodB; 

@end 

@interface MyClass : NSObject { 
    ClassA *a; 
    ClassB *b; 
} 

-(id)initWithA:(ClassA *)anA b:(ClassB *)aB; 

-(void)methodA; 
-(void)methodB; 

@end 

Ahora solo necesita invocar el método en el ivar relevante. Es más código, pero simplemente no hay herencia múltiple como característica de idioma en el objetivo-C.

+8

composición es muy a menudo un mejor enfoque de tomar que la herencia, especialmente si hacer muchas pruebas unitarias en el código. Ofrece mucha más flexibilidad ya que puede cambiar fácilmente las implementaciones sin redefinir la clase en sí. Especialmente útil cuando quieras, digamos, intercambiar ClassA y ClassB por objetos simulados. Incluso en tiempo de ejecución, las implementaciones de intercambio (por ejemplo, FTPFileStore vs LocalFileStore) se vuelven más limpias con la composición. Eso no significa que la herencia no tenga su lugar, pero la necesidad de una herencia múltiple sugeriría que vuelva a pensar en mi diseño;) – d11wtq

+1

No entiendo esto. ¿No necesita crear instancias de 'ClassA' y' ClassB'? ¿Llamar a 'methodA:' en 'MyClass' de alguna manera automáticamente llama' methodA: 'on' ClassA'? – zakdances

+1

No, pero aún puede compartir el comportamiento a través de la transmisión de mensajes, como originalmente se suponía que funcionara OOP. Si no se da cuenta inmediatamente de que necesita herencia y, en su lugar, considera una solución con composición, descubrirá que comienza a estructurar sus programas de una manera más fácil de mantener. Por supuesto, ObjC tiene herencia básica para los casos en que es correcto usarla. – d11wtq

-2

sabe usted de protocolos, los protocolos es la manera de poner en práctica la herencia múltiple

+58

-1: Los protocolos son * muy * diferentes a usar la herencia. – FreeAsInBeer

+12

+1 "Para capturar las similitudes entre las clases que no están relacionadas jerárquicamente". https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html – pokstad

+7

En este caso, donde ambos métodos serán anulados, los protocolos harán el truco. En otros casos, cuando desee utilizar la herencia para reutilizar el código, los protocolos no serían de ayuda. Sin embargo, esto generalmente se puede resolver dejando que las clases superclases se hereden entre sí, o combinándolas, generalmente hay una forma de hacerlo bien si una subclase realmente comparte código con 2 clases. –

3

Así es como me singletonPattern código como "un padre" Básicamente utiliza una combinación de protocolo y categoría.

Lo único que no puedo agregar es un nuevo "ivar", sin embargo, puedo presionarlo con el objeto asociado.

#import <Foundation/Foundation.h> 
@protocol BGSuperSingleton 
+(id) singleton1; 
+(instancetype)singleton; 
@end 

@interface NSObject (singleton) <BGSuperSingleton> 

@end 

static NSMutableDictionary * allTheSingletons; 

+(instancetype)singleton 
{ 
    return [self singleton1]; 
} 
+(id) singleton1 
{ 
    NSString* className = NSStringFromClass([self class]); 

    if (!allTheSingletons) 
    { 
     allTheSingletons = NSMutableDictionary.dictionary; 
    } 

    id result = allTheSingletons[className]; 

    //PO(result); 
    if (result==nil) 
    { 
     result = [[[self class] alloc]init]; 
     allTheSingletons[className]=result; 
     [result additionalInitialization]; 
    } 
    return result; 
} 

-(void) additionalInitialization 
{ 

} 

Siempre que quiero una clase de "heredar" esta BGSuperSingleton acabo de hacer:

#import "NSObject+singleton.h" 

y añadir @interface MyNewClass() <BGSuperSingleton>

+2

Las categorías no son de herencia múltiple. Son una forma de aplicar métodos/funciones a una clase ya existente. La herencia múltiple permite que una tercera clase sea una combinación de una o más clases (incluidas las variables). Me gustan las categorías. Las categorías son muy útiles. Pero NO son herencia múltiple. –

+0

Pero una subclase de UIViewController también puede "admitir", en este caso, un patrón singleton si lo deseo. –

+0

Técnicamente todo NSManagedObject "ahora puede llamar" [obj singleton]. Configuro los que deseo con el apoyo del protocolo. Tan bueno como la herencia múltiple de todos modos. Esto es solo si quiero que la clase secundaria sea compatible tanto con la interfaz como con la implementación del padre. Si solo la implementación, obviamente, la composición es el camino a seguir. –