java objective-c-category

¿Puede Java hacer algo como categoría en Objective C?



objective-c-category (3)

Como se mencionó en las otras respuestas, no hay nada como una categoría. Tengo algunas soluciones comunes que utilizo para algunas de las categorías en mi código de object-c cuando realizo la migración a Java. Muchas de mis categorías de objetivo-c existen porque no quiero extender las clases base de iOS, pero sí quiero agregar alguna funcionalidad a esa clase. Muchas de esas categorías de objetivos-c no agregan propiedades usando objc_SetAssociatedObject. Para esos casos utilizo una clase auxiliar estática en Java. Veamos un ejemplo usando NSString y String. Agregaré funcionalidad a ambos para agregar comillas a la cadena. Asumiremos que esto es útil y no existe para fines de ilustración. En object-c podríamos tener:

@interface NSString (MyCategory) /** * Creates and autoreleased image from self. */ - (NSString*)quotedString; @end @implementation NSString (MyCategory) - (NSString *)quotedString { return [NSString stringWithFormat:@"/"%@/"", self]; } @end

Usted llamaría a esto desde un lugar como este:

NSString *myString = @"When you''re curious, you find lots of interesting things to do."; NSString *quotedString = [myString quotedString];

Así es como implementaría esto en Java:

public class StringHelper { public static String quotedString(String that) { return ''"'' + that + ''"''; } }

Y para llamarlo:

String myString = = "When you''re curious, you find lots of interesting things to do."; String quotedString = StringHelper.quotedString(myString);

Si piensa que los métodos de categoría son métodos que envían automáticamente la variable propia como el primer argumento del método (aunque invisible), esto tiene aún más sentido.

Para su ejemplo, si no extendiera el objeto específico, podría hacer algo como:

public class ObjectHelper { public static void printDetail(Object that) { // do what it takes; } }

ACTUALIZACIÓN: Un comentarista pidió limitaciones.

Las limitaciones serían que el código está en una clase estática separada. No es tan conveniente como una categoría. Debe recordar esos nombres de clase o encontrarlos, y no obtendrá la terminación automática de sus métodos de objetos originales en el ayudante. Además, no puede usar propiedades o atributos de nivel de objeto como los que obtiene con objc_SetAssociatedObject. Podría usar un mapa hash y crear algo similar con la instancia del objeto original como una clave hash.

public class StringHelper { private static Map<String, Integer> order = new HashMap(); public static int getOrder(String that) { if(that == null) { return 0; } Integer ret = StringHelper.order.get(that); if(ret == null) { return 0; } else { return ret; } } public static void setOrder(String that, int order) { if(that != null) { StringHelper.order.put(that, order); } } }

Tampoco hay conflictos de nombres con la clase original, lo que sería más beneficioso. Los choques de nombres en las categorías de objetivos-c se consideran malos.

Considere la siguiente situación:

Object > MyClass > MyClassA, MyClassB

Si quiero algo en el nivel de Objeto, por ejemplo, agregué printDetail (); ¿Cómo puedo hacerlo en la implementación de Java? Además, puedo anular todo el método del Objeto. Por ejemplo, necesito tener un nuevo .toString (), ¿puedo anularlo? Gracias.


No, no puede, no realmente de todos modos. Objective C es un lenguaje de tipo dinámico y de ámbito, lo que lo hace muy susceptible a características como categorías. Lo más cerca que puede llegar a esto en Java es la instrumentación de clase a través de una biblioteca de manipulación de códigos de bytes como ASM o Javassist .

Pero realmente, al usar un lenguaje OO fuertemente tipado como Java, debe adoptar sus características en lugar de intentar duplicar las de otro idioma.


Todas las clases de Java finalmente tienen java.lang.Object Debido a esto, todas las Java classes inherit métodos de Object . La mitad de estos métodos son final y no se pueden overridden . Sin embargo, los otros métodos en Objeto pueden ser y son anulados
El método toString () en la clase Objeto se usa para mostrar cierta información con respecto a cualquier objeto.
Así que puedes anularlo de acuerdo a tu ser ...
EX..

public class Test{ @Override public String toString() { /// staff } }