2012-03-14 15 views
16

siguiente situación:¿Puede Java hacer algo como categoría en Objective C? Considere

Object > MyClass > MyClassA, MyClassB 

Si quiero algo en el nivel de objeto, por ejemplo, he añadido 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 .toString() completamente nuevo, ¿puedo anularlo? Gracias.

Respuesta

28

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

Pero realmente, cuando se usa un lenguaje OO fuertemente tipado como Java, debe abarcar sus características en lugar de intentar duplicar las de otro idioma.

+0

great answer .. !! –

+0

Aunque el comentario es un tanto académico, creo que el problema es el factoring: p. si quiero una manera de aleatorizar el orden de las cosas en una matriz, podría decir "semánticamente que es lo más correcto una acción que le pediría a la matriz que realice, por lo tanto, la agregaré sintácticamente como método en la matriz". Lo que no creo es que los recortes sean fuertemente tipados u orientados a objetos. Pero, no, no es Javaish. – Tommy

+1

¿No es C# un lenguaje OO fuertemente tipado? Porque C# ofrece esta capacidad a través de los métodos de extensión. ¿Qué hay de malo en tomar cosas buenas de otros idiomas? Es una forma de progresar ... – obe

2

Todas las clases de Java eventualmente tienen java.lang.Object Debido a esto, todos los métodos Java classes inherit de Object. La mitad de estos métodos son final y no pueden ser overridden. Sin embargo, los otros métodos en Objeto pueden ser anulados
El método toString() en la clase Object se usa para mostrar información sobre cualquier objeto.
Así se puede reemplazar de acuerdo a su auto ...
EX ..

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

Ya veo. Uso Ruby, que me permite anular el objeto de nivel superior. – DNB5brims

11

Como se mencionó en las otras respuestas, no hay nada realmente como una categoría. Tengo algunas soluciones comunes que uso para algunas de las categorías en mi código objetivo-c cuando transfiero a java. Muchas de mis categorías 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 objetivo-c no agregan propiedades usando objc_SetAssociatedObject. Para esos casos, uso 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 propósitos de ilustración. En Objective-C que 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 

que llamarían esto desde un sitio como este:

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

Así es como me gustaría implementar esto en Java:

public class StringHelper { 

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

Y para llamar it:

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

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

Para su ejemplo, si yo no extender 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 pedido 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á autocompletado en sus métodos de objetos originales en el ayudante. Además, no puede usar propiedades o propiedades de nivel de objeto como las que obtiene con objc_SetAssociatedObject. Puede usar un mapa hash y crear algo similar con la instancia original del objeto 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 una ventaja. Los conflictos de nombres en las categorías objetivo-c se consideran malos.

+0

Me gusta esta respuesta porque me da una solución. ¡Gracias! –

+0

@ptoinson ¿Qué limitaciones hay si lo comparamos con la categoría en iOS? – NghiaDao

+0

@NghiaDao - Se agregaron limitaciones a una actualización de la respuesta. – ptoinson

Cuestiones relacionadas