relaciones programacion orientada objetos entre ejemplos diagrama datos clases asociacion agregacion objective-c ios composition

objective c - programacion - ¿Cómo funciona la composición de clases en iOS?



relaciones entre clases programacion orientada a objetos (2)

Digamos que tengo la propiedad A en classA y la propiedad B en classB y quiero que classAB tenga ambas propiedades A y B Todavía no entiendo cómo hacer que todo esto funcione con la composición .

Me doy cuenta de que esto se puede hacer con herencia, pero quiero aprender a hacer esto con la composición . He visto ejemplos y todavía no entiendo cómo funciona todo.


Crea una nueva clase, que tiene instancias de classA y classB como variables miembro. Luego implementas las propiedades pasando a través de los métodos get / set.

@interface ClassAB { ClassA *objectA; ClassB *objectB; } @property (nonatomic,strong) id propertyA; @property (nonatomic,strong) id propertyB; @end @implementation ClassAB - (id)propertyA { return objectA.propertyA; } - (void)setPropertyA:(id)value { objectA.propertyA = value; } - (id)propertyB { return objectB.propertyB; } - (void)setPropertyB:(id)value { objectB.propertyB = value; } @end

Y eso es lo que es la composición. Algunos idiomas tienen una sintaxis especial para hacer esto (por ejemplo, en Ruby puedes incluir un conjunto de métodos de una clase / módulo en otra), pero Objective-C no lo permite.

Una cosa que puede hacer en Objective-C es capturar los mensajes enviados a su objeto que no tienen un método asociado y reenviarlos a otro objeto. Este truco es útil si está escribiendo una clase que se presentará como otra clase, o si hay muchos mensajes diferentes para reenviar y no desea escribirlos todos manualmente.

La desventaja de usar el reenvío de mensajes es que renuncia a un poco de control y puede ser más difícil predecir cuándo un mensaje será manejado por su clase o la clase de reenvío. Por ejemplo, si una superclase implementa un método, ese método se ejecutará y el código de reenvío no se llamará.


Suponiendo que ClassA y ClassB se implementan como usted dijo, esto funciona muy bien y es fácilmente extensible.

@interface ClassAB : NSObject @property int a; @property int b; @property ClassA *aObject; @property ClassB *bObject; @end @implementation ClassAB @dynamic a, b; @synthesize aObject, bObject; -(id) forwardingTargetForSelector:(SEL)aSelector { if ([aObject respondsToSelector:aSelector]) return aObject; else if ([bObject respondsToSelector:aSelector]) return bObject; return nil; } @end int main(int argc, const char * argv[]) { @autoreleasepool { ClassA *a = [ClassA new]; ClassB *b = [ClassB new]; ClassAB *ab = [ClassAB new]; ab.aObject = a; ab.bObject = b; ab.a = 10; ab.b = 20; NSLog(@"%i, %i", a.a, b.b); // outputs 10, 20 } return 0; }