Come accennato nelle altre risposte, non c'è nulla di veramente come una categoria. Ho alcune soluzioni comuni che uso per alcune delle categorie nel mio codice obiettivo-c durante il porting su java. Molte delle mie categorie obiettivo-c esistono perché non voglio estendere le classi base iOS ma voglio aggiungere alcune funzionalità a quella classe. Molte di queste categorie obiettivo-c non aggiungono proprietà usando objc_SetAssociatedObject. Per quei casi uso una classe helper statica in Java. Diamo un'occhiata ad un esempio usando NSString e String. Aggiungerò funzionalità a entrambi per aggiungere virgolette alla stringa. Supponiamo che questo sia utile e non esiste ai fini dell'illustrazione. In Objective-C potremmo avere:
@interface NSString (MyCategory)
/**
* Creates and autoreleased image from self.
*/
- (NSString*)quotedString;
@end
@implementation NSString (MyCategory)
- (NSString *)quotedString
{
return [NSString stringWithFormat:@"\"%@\"", self];
}
@end
si potrebbe chiamare questo da un posto come questo:
NSString *myString = @"When you're curious, you find lots of interesting things to do.";
NSString *quotedString = [myString quotedString];
Ecco come vorrei implementare questo in Java:
public class StringHelper {
public static String quotedString(String that) {
return '"' + that + '"';
}
}
E per chiamare it:
String myString = = "When you're curious, you find lots of interesting things to do.";
String quotedString = StringHelper.quotedString(myString);
Se si pensa ai metodi di categoria come metodi che inviano automaticamente la variabile autonoma come primo argomento del metodo (anche se invisibile), ciò ha ancora più senso.
Per esempio, se non vorrei estendere l'oggetto specifico, potrei fare qualcosa di simile:
public class ObjectHelper {
public static void printDetail(Object that) {
// do what it takes;
}
}
AGGIORNAMENTO: Un commentatore ha chiesto per le limitazioni.
Le limitazioni sarebbero che il codice si trova in una classe statica separata. Non è conveniente come una categoria. Devi ricordare quei nomi di classe, o trovarli, e non otterrai il completamento automatico sui metodi degli oggetti originali nell'help. Inoltre, non è possibile utilizzare proprietà o attributi a livello di oggetto come si ottiene con objc_SetAssociatedObject. È possibile utilizzare una mappa hash e creare qualcosa di simile con l'istanza dell'oggetto originale come chiave 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);
}
}
}
ci sono anche scontri nome con la classe originale, che sarebbe più di un vantaggio. Le collisioni di nomi nelle categorie obiettivo-c sono considerate cattive.
ottima risposta .. !! –
Anche se il commento è un po 'accademico, penso che il problema sia il factoring: ad es. se voglio un modo per randomizzare l'ordine delle cose in un array, potrei dire "semanticamente è più giusto un'azione che chiederei all'array di eseguire, quindi aggiungerò sintatticamente come metodo sull'array". Che non credo tagli contro essere fortemente dattiloscritto o orientato agli oggetti. Ma no, non è Javaish. – Tommy
C# non è un linguaggio OO fortemente tipizzato? Perché C# offre questa capacità attraverso i metodi di estensione. Cosa c'è di male nel prendere roba buona da altre lingue? È un modo per progredire ... – obe