¿Puede una interfaz de Objective c tener más de una implementación?


¿Puede una interfaz de Objective c tener más de una implementación? Ejemplo Podría tener una interfaz pero 2 implementaciones una donde utilizo una matriz u otra donde utilizo una pila..etc para implementarlo.

Si es así, ¿cómo lo llamas / sintaxis?

Author: RedBlueThing, 2010-03-06

4 answers

Objective-C tiene el concepto de un Protocolo , que es la especificación de una interfaz. A través de los protocolos , Objective-C soporta completamente la herencia múltiple de especificación (pero no la implementación). Por lo tanto, un poco confusamente, la sintaxis @interface realmente define la clase (implementación), que solo admite herencia única, pero puede especificar la implementación de muchas / múltiples herencias de Protocolos, o especificaciones de interfaces. Al final, esto es muy similar en naturaleza a Java.

Por ejemplo:

@protocol SomeInterface
- (void)interfaceMethod1;
- (void)interfaceMethod2;
@end

@interface SomeClass:NSObject <SomeInterface>
@end 

@interface AnotherClass:NSObject <SomeInterface>
@end 

Las instancias de SomeClass o AnotherClass ambas afirman que proporcionan la implementación requerida para el SomeInterface protocolo .

Objective-C se escribe dinámicamente y no requiere que el objeto especifique realmente el mensaje que se le envía. En otras palabras, puede llamar indiscriminadamente a cualquier método que desee en SomeClass, ya sea que esté especificado en su interfaz o en cualquiera de sus protocolos o no (no es que esto sea necesariamente algo productivo o positivo).

Por lo tanto, todo lo siguiente compilaría (aunque con advertencias) y correría bien, aunque los mensajes / métodos sin implementación es básicamente un no op en este caso. Objective-C tiene un proceso bastante complicado (y muy genial) de manejar la llamada / reenvío de métodos que está un poco más allá del alcance de esta pregunta.

SomeClass * someObject = [[SomeClass alloc] init;
[someObject someUnspecifiedMethod];  // Compiles with warning - no op
[someObject interfaceMethod1];

Si desea definir algo que puede ser cualquier clase ( @ interfaz ) tipo pero implementa una interfaz específica (@protocol ), puede usar algo como esto:

id <SomeInterface> obj;

obj podría contener un objeto SomeClass o AnotherClass.

 26
Author: rcw3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-06 17:34:14

Quizás deberías probar el patrón Cocoa llamado Cluster de clase. Para empezar a usarlo necesitas crear una clase pública llamada SomeClass y dos subclases privadas SomeArrayClass y SomeStackClass. Cuando necesite usar stack, su constructor de clase pública creará una instancia de SomeStackClass y la devolverá como instancia disponible públicamente de SomeClass.

 24
Author: Roman Busygin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-28 19:59:31

(Si le das un voto a esto, por favor dale un voto a Roman his su respuesta fue la primera, es correcta, solo le faltaba un ejemplo).

Usted está hablando de un Cluster de Clase. Para un ejemplo, mira la clase NSString.

Hay NSString:

@interface NSString : NSObject

Y NSMutableString:

@interface NSMutableString : NSString

Ambos declaran un conjunto extremadamente pequeño de métodos en la declaración de la clase core. Si fuera a subclase NSString para implementar su propia string class, solo necesitaría implementar esos métodos principales. Todos los demás métodos implementados en NSString se implementan en términos de esos métodos principales. Y, del mismo modo, los métodos de mutación se implementan utilizando los métodos primitivos declarados en el núcleo de NSMutableString.

Ahora, obviamente, implementar toda la mutabilidad a través de - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString (el método de un núcleo) sería extremadamente ineficiente. Por lo tanto, en tiempo de ejecución, notará que en realidad nunca tiene una instancia de NSString o NSMutableString , pero solo instancias de subclases (que, en realidad, no son realmente subclases... pero también podrían estar en el contexto de esta discusión).

Y esas subclases the la clase de implementación utilizada en tiempo de ejecución overri anula casi todos los métodos de NSString y NSMutableString para proporcionar implementaciones altamente optimizadas de las operaciones específicas.

Entonces, harías algo como:

@interface MyAbstractClass : NSObject
... declare factory methods here ...
... declare core methods here ...
@end

@interface MyAbstractClass(AdditionalFunctionality)
... declare convenience here ...
@end

Entonces, en el implementación, implementar todos los métodos básicos como @throw @"Must use subclass" y todos los métodos AdditionalFunctionality en términos de los métodos básicos.

Esto podría ser completamente privado not no en un encabezado en absoluto, incluso:

@ interfaz MyStackClass: MyAbstractClass @ end

@ implementation MyStackClass ... implemente los métodos principales y anule los métodos de funcionalidad adicionales que necesitan optimización ... @ end

Repita para sus tipos adicionales de clases. Luego, implementar métodos de fábrica en MyAbstractClass que devuelve instancias de las subclases, según sea necesario.

 20
Author: bbum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-06 19:35:45

Quieres decir, por ejemplo, así:

@interface MasterViewController : 
  UIViewController <GKPeerPickerControllerDelegate, 
                    GKSessionDelegate,
                    UITextFieldDelegate,
                    UITableViewDelegate,
                    AVAudioRecorderDelegate> {
}
 3
Author: Tuomas Pelkonen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-06 17:00:15