Может ли Java сделать что-то вроде категории в Objective C? - PullRequest
18 голосов
/ 14 марта 2012

Рассмотрим следующую ситуацию:

Object > MyClass > MyClassA, MyClassB

Если я хочу что-то на уровне объекта, например, я добавил printDetail ();Как я могу сделать это в реализации Java?Кроме того, я могу переопределить все методы объекта.Например, мне нужно иметь совершенно новый .toString (), могу ли я его переопределить?Спасибо.

Ответы [ 3 ]

28 голосов
/ 14 марта 2012

Нет, не может, на самом деле нет.Objective C - это язык с динамической типизацией и областями видимости, который делает его очень пригодным для таких функций, как категории.Наиболее близким к этому в Java является инструментарий классов через библиотеку манипулирования байтовым кодом, такую ​​как ASM или Javassist .

Но на самом деле, при использовании строго типизированного ООВ языке, подобном Java, вы должны использовать его возможности, а не пытаться дублировать возможности другого языка.

12 голосов
/ 23 января 2014

Как уже упоминалось в других ответах, на самом деле нет ничего похожего на категорию.У меня есть некоторые общие решения, которые я использую для некоторых категорий в моем коде Objective-C при портировании на Java.Многие из моих категорий target-c существуют, потому что я не хочу расширять базовые классы iOS, но хочу добавить некоторые функциональные возможности в этот класс.Многие из этих категорий target-c не добавляют свойства, используя objc_SetAssociatedObject.Для этих случаев я использую статический вспомогательный класс в Java.Давайте рассмотрим пример с использованием NSString и String.Я добавлю функциональность к обоим, чтобы добавить кавычки в строку.Мы предполагаем, что это полезно и не существует в целях иллюстрации.В target-c у нас может быть:

@interface NSString (MyCategory)

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

@end

@implementation NSString (MyCategory)

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

@end

Вы бы назвали это откуда-то так:

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

Вот как я бы реализовал это в Java:

public class StringHelper {

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

И чтобы назвать это:

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

Если вы думаете о методах категории как о методах, которые автоматически отправляют переменную self в качестве первого аргумента метода (хотя и невидимого), то это имеет еще больший смысл.

Для вашего примера, если бы я не расширил конкретный объект, я мог бы сделать что-то вроде:

public class ObjectHelper {

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

ОБНОВЛЕНИЕ: Комментатор попросил ограничения.

Ограничения будут заключаться в том, что код находится в отдельном статическом классе.Это не так удобно, как категория.Вы должны запомнить эти имена классов или найти их, и вы не получите автоматическое завершение ваших исходных методов объектов в помощнике.Кроме того, вы не можете использовать свойства или атрибуты уровня объекта, как вы получаете с objc_SetAssociatedObject.Вы можете использовать хэш-карту и создать нечто подобное с исходным экземпляром объекта в качестве хэш-ключа.

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

Также нет столкновений имен с исходным классом, что было бы большим преимуществом.Столкновения с именами в объективных категориях считаются плохими.

2 голосов
/ 14 марта 2012

Все классы Java в конечном итоге имеют java.lang.Object Из-за этого все Java classes inherit методы из Object.Половина из этих методов final и не может быть overridden.Однако другие методы в Object могут быть и могут быть переопределены
Метод toString () в классе Object используется для отображения некоторой информации, касающейся любого объекта.
ИтакВы можете переопределить его в соответствии со своим собственным ...
EX ..

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