2012-03-14 1 views
16

Pensez situation suivante:Est-ce que Java peut faire quelque chose comme une catégorie en Objective C?

Object > MyClass > MyClassA, MyClassB 

Si je veux quelque chose dans le niveau de l'objet, par exemple, j'ajouté printDetail(); Comment puis-je le faire dans l'implémentation Java? De plus, puis-je remplacer toute la méthode de l'objet. Par exemple, j'ai besoin d'un tout nouveau .toString(), puis-je le remplacer? Merci.

Répondre

28

Non, il ne peut pas, pas vraiment de toute façon. L'objectif C est un langage dynamiquement typé et étendu, ce qui le rend très accessible aux fonctionnalités comme les catégories. Le plus proche que vous pouvez en venir à cela en Java est l'instrumentation de classe via une bibliothèque de manipulation de code octet comme ASM ou Javassist. Mais en réalité, lorsque vous utilisez un langage OO fortement typé comme Java, vous devriez adopter ses caractéristiques plutôt que d'essayer de dupliquer celles d'un autre langage.

+0

bonne réponse .. !! –

+0

Bien que le commentaire soit quelque peu académique, je pense que la question est l'affacturage: par exemple. si je veux un moyen de randomiser l'ordre des choses dans un tableau, je pourrais dire sémantiquement que c'est à juste titre une action que je demanderais au tableau de faire, donc je l'ajouterais syntaxiquement comme une méthode sur un tableau. Ce que je ne pense pas coupe contre être fortement typé ou orienté objet. Mais non, ce n'est pas Javaish. – Tommy

+1

C# n'est-il pas un langage OO fortement typé? Parce que C# offre cette possibilité grâce aux méthodes d'extension. Quel est le problème de prendre de bonnes choses d'autres langues? C'est un moyen de progresser ... – obe

2

Toutes les classes Java ont finalement java.lang.Object Pour cette raison, toutes les méthodes Java classes inherit de Object. La moitié de ces méthodes sont final et ne peuvent pas être overridden. Cependant, les autres méthodes dans Objet peuvent être et sont remplacées
La méthode toString() de la classe Object est utilisée pour afficher des informations sur n'importe quel objet.
Vous pouvez remplacer selon votre auto ...
EX ..

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

Je vois. J'utilise ruby, ce qui me permet de remplacer l'objet de premier niveau. – DNB5brims

11

Comme mentionné dans les autres réponses, il n'y a rien vraiment une catégorie. J'ai quelques solutions communes que j'utilise pour certaines des catégories de mon code objectif-c lors du portage sur Java. Beaucoup de mes catégories objectives-c existent parce que je ne veux pas étendre les classes de base iOS mais je veux ajouter quelques fonctionnalités à cette classe. Beaucoup de ces catégories objectives-c n'ajoutent pas de propriétés en utilisant objc_SetAssociatedObject. Pour ces cas, j'utilise une classe d'aide statique en Java. Regardons un exemple en utilisant NSString et String. Je vais ajouter des fonctionnalités à la fois pour ajouter des guillemets à la chaîne. Nous supposerons que cela est utile et n'existe pas à des fins d'illustration. En Objective-C, nous pourrions avoir:

@interface NSString (MyCategory) 

/** 
* Creates and autoreleased image from self. 
*/ 
- (NSString*)quotedString; 

@end 

@implementation NSString (MyCategory) 

- (NSString *)quotedString 
{ 
    return [NSString stringWithFormat:@"\"%@\"", self]; 
} 

@end 

Vous appelleraient cela de quelque part comme ceci:

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

Voilà comment j'implémenter dans Java:

public class StringHelper { 

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

Et pour appeler il:

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

Si vous considérez les méthodes de catégorie comme des méthodes qui envoient automatiquement la variable self comme premier argument de méthode (bien qu'invisible), cela devient encore plus logique.

Pour votre exemple, si je ne prolongera pas l'objet spécifique, je pourrais faire quelque chose comme:

public class ObjectHelper { 

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

MISE À JOUR: Un intervenant a demandé des limitations.

Les limitations seraient que le code soit dans une classe statique distincte. Ce n'est pas aussi pratique qu'une catégorie. Vous devez vous souvenir de ces noms de classe, ou les trouver, et vous n'obtiendrez pas la complétion automatique sur vos méthodes d'objets d'origine dans l'assistant. De même, vous ne pouvez pas utiliser les propriétés ou les attributs de niveau objet comme vous l'obtenez avec objc_SetAssociatedObject. Vous pouvez utiliser une carte de hachage et créer quelque chose de similaire avec l'instance d'objet d'origine en tant que clé de hachage.

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); 
     } 
    } 
} 

Il n'y a pas non plus de conflit de noms avec la classe d'origine, ce qui serait plus avantageux. Les conflits de noms dans les catégories d'objectifs-c sont considérés comme mauvais.

+0

J'aime mieux cette réponse parce qu'elle me donne une solution de contournement. Merci! –

+0

@ptoinson Quelles sont les limitations si on compare de cette façon avec la catégorie dans iOS? – NghiaDao

+0

@NghiaDao - Limitations ajoutées à une mise à jour de la réponse. – ptoinson

Questions connexes