Herencia múltiple de Objective-C


88

Tengo 2 clases, una incluye el método A y la otra incluye el método B. Entonces, en una nueva clase, necesito anular los métodos methodA y methodB. Entonces, ¿cómo puedo lograr una herencia múltiple en el objetivo C? Estoy un poco confundido con la sintaxis.

Respuestas:


136

Objective-C no admite herencia múltiple y no la necesita. Composición de uso:

@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 del lenguaje en aim-C.


8
La composición es a menudo un mejor enfoque que la herencia, especialmente si haces 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í. Particularmente útil cuando desea, por ejemplo, intercambiar ClassA y ClassB por objetos simulados. Incluso en tiempo de ejecución, el intercambio de implementaciones (por ejemplo, FTPFileStore vs LocalFileStore) se vuelve más limpio con la composición. Sin embargo, eso no significa que la herencia no tenga su lugar, pero la necesidad de una herencia múltiple sugeriría que reconsiderara mi diseño;)
d11wtq

1
No entiendo esto. ¿No necesitas crear una instancia ClassAy ClassB? Hace llamar methodA:en MyClassalguna manera llamar automáticamente methodA:en ClassA?
zakdances

1
No, pero aún puede compartir el comportamiento a través del paso de mensajes, la forma en que originalmente se suponía que funcionaba OOP. Si no piensa inmediatamente que necesita herencia y, en cambio, considera una solución utilizando la composición, verá que comienza a estructurar sus programas de una manera más fácil de mantener. Por supuesto, ObjC tiene una herencia básica para los casos en los que es correcto usarlo.
d11wtq


1
d11wtq, ¡gran respuesta! Además, el reenvío de mensajes le permite omitir el paso de volver a implementar el método A y el método B. Los mensajes se pueden reenviar automáticamente a los objetos apropiados con solo un poco de trabajo. developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
arsenius

3

Así es como codifico singletonPattern como "padre" Básicamente utilicé 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 que una clase "herede" este BGSuperSingleton, simplemente hago:

#import "NSObject+singleton.h"

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


2
Las categorías no son herencia múltiple. Son una forma de agregar 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.
Lloyd Sargent

Pero una subclase de UIViewController también puede "soportar", en este caso, el patrón singleton si así lo desea.
Septiadi Agus

Técnicamente, todos los NSManagedObject "ahora pueden llamar" [obj singleton]. Yo configuro los que deseo con el apoyo del protocolo. De todos modos, tan bueno como la herencia múltiple. Esto es solo si quiero que la clase secundaria admita tanto la interfaz como la implementación del padre. Si solo la implementación, obviamente la composición es el camino a seguir.
Septiadi Agus

Simplemente agregar el protocolo como <BGSuperSingleton> no hace que las clases puedan llamar al método "singleton". Todavía tienes que implementarlo ...
CommaToast

-4

¿Sabes de Protocolos, protocolos es la forma de implementar la herencia múltiple?


12
+1 "Para capturar similitudes entre clases que no están relacionadas jerárquicamente". developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…
pokstad

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

puede combinar el protocolo con una categoría o composición.
Septiadi Agus

-1 porque los protocolos no existen para la herencia múltiple en absoluto. De manera similar JAVA, Interfacesno deben proporcionar ni imitar herencia múltiple.
thesummersign

1
@FreeAsInBeer De la propia documentación de Apple Un protocolo declara una interfaz programática que cualquier clase puede elegir implementar. Los protocolos hacen posible que dos clases relacionadas lejanamente por herencia se comuniquen entre sí para lograr un objetivo determinado. Por tanto, ofrecen una alternativa a la subclasificación . Como puede ver, Apple está usando explícitamente subclases, es decir, heredando. Quizás Nikesh incluir esto en su propia respuesta sería útil para aclarar su argumento
Cariño
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.