Extensión de clase vs categoría de clase

82

Las extensiones de clase @interface Class () son mucho más poderosas y pueden inyectar variables en la clase. Las categorías @interface Class (Category)no pueden.

¿Qué otras diferencias existen y cuándo se debe usar una categoría en lugar de una extensión de clase?

AWF4vk
fuente
las categorías son código real. así es como agregas funciones a una clase. Las extensiones son (en términos muy generales) más simplemente azúcar sintáctico, para señalar ciertas ideas sobre privacidad, etc., a otros programadores. las extensiones no contienen código y no son código.
Fattie
Para conocer las extensiones que se utilizan en Swift, consulte esta pregunta: stackoverflow.com/questions/24142829/…
Suragch

Respuestas:

91

La principal diferencia es que con una extensión, el compilador esperará que implementes los métodos dentro de tu main @implementation, mientras que con una categoría tienes un @implementationbloque separado . Por lo tanto, debería usar una extensión en la parte superior de su .marchivo principal (el único lugar en el que debería preocuparse por los ivars, por cierto); se supone que es solo eso, una extensión .

jtbandes
fuente
41
Una extensión es mejor para los métodos privados que le gustaría declarar en su .marchivo. Lo uso para esto todo el tiempo. Las categorías son más útiles cuando desea agrupar sus métodos en diferentes secciones, categorías :), o cuando desea agregar código a clases existentes que no creó.
jtbandes
1
También puede agregar almacenamiento adicional en extensiones de clase usando propiedades.
Paul.s
23
Las extensiones de clase también fueron diseñadas específicamente para permitir que una propiedad sea pública readonlyy privada readwrite. No puedo hacer eso con categorías (una elección de diseño consciente).
bbum
¿Por qué Google utiliza la categoría para implementar métodos privados en lugar de extensión? p .
Ryan
extensions requiere que todos los métodos se implementen en el bloque @implementation, también proporciona mejoras para las variables. Pero básicamente estamos tratando de poner algunos de los métodos privados en lugar de usar variables privadas, por lo que en ese caso preferimos la categoría en lugar de la extensión
Ankit Thakur
29

Una extensión de clase tiene cierta similitud con una categoría, pero solo se puede agregar a una clase para la que tiene el código fuente en tiempo de compilación (la clase se compila al mismo tiempo que la extensión de clase). Los métodos declarados por una extensión de clase se implementan en el bloque @implementation para la clase original, por lo que no puede, por ejemplo, declarar una extensión de clase en una clase de marco, como una clase Cocoa o Cocoa Touch como NSString.

La sintaxis para declarar una extensión de clase es similar a la sintaxis de una categoría y se ve así:

@interface ClassName ()
@end

Debido a que no se proporciona ningún nombre entre paréntesis, las extensiones de clase a menudo se denominan categorías anónimas.

A diferencia de las categorías normales, una extensión de clase puede agregar sus propias propiedades y variables de instancia a una clase. Si declara una propiedad en una extensión de clase, así:

@interface XYZAnimal () {
    id _someCustomInstanceVariable;
}
...
@end

En mi humilde opinión, es mejor pensar en las extensiones de clase como una interfaz privada para una clase. La interfaz principal (en su archivo .h) actúa como la interfaz pública que define el contrato de comportamiento de la clase con otras clases.

Use extensiones de clase para ocultar información privada

Las extensiones de clase se utilizan a menudo para ampliar la interfaz pública con propiedades o métodos privados adicionales para su uso dentro de la implementación de la propia clase. Es común, por ejemplo, definir una propiedad como de solo lectura en la interfaz, pero como lectura y escritura en una extensión de clase declarada arriba de la implementación, para que los métodos internos de la clase puedan cambiar el valor de la propiedad directamente.

Como ejemplo, la clase XYZPerson podría agregar una propiedad llamada uniqueIdentifier, diseñada para realizar un seguimiento de información como un número de seguro social en los EE. UU.

Por lo general, se requiere una gran cantidad de papeleo para tener un identificador único asignado a una persona en el mundo real, por lo que la interfaz de la clase XYZPerson puede declarar esta propiedad como de solo lectura y proporcionar algún método que solicite que se asigne un identificador, como este:

@interface XYZPerson : NSObject
    ...
    @property (readonly) NSString *uniqueIdentifier;
    - (void)assignUniqueIdentifier;
@end

Para que la clase XYZPerson pueda cambiar la propiedad internamente, tiene sentido volver a declarar la propiedad en una extensión de clase definida en la parte superior del archivo de implementación de la clase:

@property (readwrite) NSString *uniqueIdentifier;

Nota: El atributo de lectura y escritura es opcional, porque es el predeterminado. Es posible que desee utilizarlo al volver a declarar una propiedad, para mayor claridad.

John Doe
fuente
7

Las categorías son una característica del lenguaje Objective-C que le permite agregar nuevos métodos a una clase existente. Las extensiones son un caso especial de categorías que le permiten definir métodos que deben implementarse en el bloque de implementación principal.

Las declaraciones privadas pueden estar en extensiones de clase, que principalmente son algunas propiedades, porque no tenemos necesidad de declarar un método antes de llamarlo.

Julie Yu
fuente
"que debe declararse en el bloque de implementación principal". -> que debe ser "implementado" en el bloque de implementación principal
Fawkes
Gracias, lo modifiqué.
Julie Yu
0

extensión ios similar a c #, clase abstracta de java o
categoría ios de interfaz similar a la extensión de clase c #

Add080bbA
fuente
Java no admite métodos de extensión
someUser
lo siento ! Error tipográfico de copiar y pegar. ios categoría similar a la extensión de clase c #.
Add080bbA
¿Puede agregar un ejemplo sobre?
Pedro Trujillo