objective c - Protocolo frente a categoría
objective-c objective-c-category (7)
¿Alguien puede explicar las diferencias entre los Protocolos y las Categorías en Objective-C? ¿Cuándo usas uno sobre el otro?
Categorías:
Una categoría es una forma de agregar nuevos métodos a todas las instancias de una clase existente sin modificar la clase en sí misma.
Utiliza una categoría cuando desea agregar funcionalidad a una clase existente sin derivar de esa clase o volver a escribir la clase original.
Digamos que está utilizando objetos NSView
en cocoa, y desea desear que todas las instancias de NSView
puedan realizar alguna acción. Obviamente, no puede reescribir la clase NSView
, e incluso si deriva de ella, no todos los objetos NSView
en su programa serán de su tipo derivado. La solución es crear una categoría en NSView
, que luego usará en su programa. Mientras #import
el archivo del encabezado que contiene tu declaración de categoría, aparecerá como si cada objeto NSView
respondiera a los métodos que definiste en el archivo fuente de la categoría.
Protocolos:
Un protocolo es una colección de métodos que cualquier clase puede elegir implementar.
Utiliza un protocolo cuando desea proporcionar una garantía de que cierta clase responderá a un conjunto específico de métodos. Cuando una clase adopta un protocolo, promete implementar todos los métodos declarados en el encabezado del protocolo. Esto significa que cualquier otra clase que use esa clase puede estar segura de que esos métodos se implementarán, sin necesidad de saber nada más sobre la clase.
Esto puede ser útil al crear una familia de clases similares que necesitan comunicarse con una clase común de "controlador". La comunicación entre la clase de controlador y las clases controladas se puede empaquetar en un solo protocolo.
Nota al margen: el lenguaje objetivo-c no admite la herencia múltiple (una clase solo puede derivar de una superclase), pero los protocolos pueden proporcionar la misma funcionalidad porque una clase puede ajustarse a varios protocolos diferentes.
Según entiendo, los Protocolos son un poco como las Interfaces de Java. Los protocolos declaran métodos, pero la implementación depende de cada clase. Las categorías parecen ser algo así como los mixins de Ruby. Con Categorías puede agregar métodos a las clases existentes. Incluso clases incorporadas.
Un protocolo dice: "aquí hay algunos métodos que me gustaría que implementaras". Una categoría dice: "Estoy ampliando la funcionalidad de esta clase con estos métodos adicionales".
Ahora, sospecho que su confusión proviene del uso de Apple de la frase "protocolo informal". Aquí está el punto clave (y el más confuso): un protocolo informal en realidad no es un protocolo en absoluto. En realidad es una categoría en NSObject. Cocoa utiliza protocolos informales de forma generalizada para proporcionar interfaces a los delegados. Como la sintaxis de @protocol
no permitía métodos opcionales hasta Objective-C 2.0, Apple implementó métodos opcionales para no hacer nada (o devolver un valor ficticio) y métodos necesarios para lanzar una excepción. No había forma de hacer cumplir esto a través del compilador.
Ahora, con Objective-C 2.0, la sintaxis de @protocol
admite la palabra clave @optional
, marcando algunos métodos en un protocolo como opcional. Por lo tanto, su clase se ajusta a un protocolo siempre que implemente todos los métodos marcados como @required
. El compilador puede determinar si su clase implementa todos los métodos necesarios, lo cual es un gran ahorro de tiempo. El iPhone SDK utiliza exclusivamente la sintaxis Objective-C 2.0 @protocol
, y no puedo pensar en una buena razón para no usarlo en ningún nuevo desarrollo (excepto para las aplicaciones Mac OS X Cocoa que deben ejecutarse en versiones anteriores de Mac OS X).
Los protocolos son contratos para implementar los métodos especificados. Cualquier objeto que se ajuste a un protocolo acepta proporcionar implementaciones para esos métodos. Un buen uso de un protocolo sería definir un conjunto de métodos de devolución de llamada para un delegado (donde el delegado debe responder a todos los métodos).
Las categorías proporcionan la capacidad de extender un objeto actual al agregarle métodos (métodos de clase o instancia). Un buen uso para una categoría sería extender la clase NSString para agregar una funcionalidad que no estaba allí antes, como agregar un método para crear una nueva cadena que convierta el receptor en 1337 5P34K.
NSString *test = @"Leet speak";
NSString *leet = [test stringByConvertingToLeet];
Un protocolo le permite declarar una lista de métodos que no están limitados a ninguna clase o categoría en particular. Los métodos declarados en el protocolo pueden ser adoptados en cualquier clase / categoría. Una clase o categoría que adopta un protocolo debe implementar todos los métodos requeridos declarados en el protocolo.
Una categoría le permite agregar métodos adicionales a una clase existente, pero no permiten variables de instancia adicionales. Los métodos que agrega la categoría se vuelven parte del tipo de clase.
Definiciones de la "Programación en Objective-C" de SGKochan:
Categorías:
Una categoría proporciona una manera fácil de modularizar la definición de una clase en grupos o categorías de métodos relacionados. También le ofrece una manera fácil de extender una definición de clase existente sin siquiera tener acceso al código fuente original para la clase y sin tener que crear una subclase.
Protocolos:
Un protocolo es una lista de métodos que se comparte entre las clases. Los métodos enumerados en el protocolo no tienen implementaciones correspondientes; están destinados a ser implementados por otra persona (¡como usted!). Un protocolo proporciona una forma de definir un conjunto de métodos que de alguna manera están relacionados con un nombre específico. Los métodos generalmente están documentados para que sepa cómo se comportarán y para que pueda implementarlos en sus propias definiciones de clase, si lo desea. Un protocolo enumera un conjunto de métodos, algunos de los cuales puede implementar de manera opcional y otros que debe implementar. Si decide implementar todos los métodos requeridos para un protocolo en particular, se dice que se conforma o adopta ese protocolo. Puede definir un protocolo donde todos los métodos son opcionales o uno donde todos son obligatorios.
Un protocolo es lo mismo que una interfaz en Java: es esencialmente un contrato que dice: "Cualquier clase que implemente este protocolo también implementará estos métodos".
Una categoría, por otro lado, solo une métodos a una clase. Por ejemplo, en Cocoa , puedo crear una categoría para NSObject
que me permita agregar métodos a la clase NSObject
(y, por supuesto, todas las subclases), aunque realmente no tengo acceso a NSObject
.
Para resumir: un protocolo especifica qué métodos implementará una clase; una categoría agrega métodos a una clase existente.
El uso adecuado de cada uno, entonces, debe ser claro: utilice protocolos para declarar un conjunto de métodos que una clase debe implementar, y use categorías para agregar métodos a una clase existente.