Может ли Java сделать что-то вроде категории в Objective C? - программирование
Подтвердить что ты не робот

Может ли Java сделать что-то вроде категории в Objective C?

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

Object > MyClass > MyClassA, MyClassB

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

4b9b3361

Ответ 1

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

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

Ответ 2

Как уже упоминалось в других ответах, нет ничего действительно подобного категории. У меня есть некоторые общие решения, которые я использую для некоторых категорий в моем коде objective-c при переносе на java. Многие из моих категорий objective-c существуют, потому что я не хочу расширять базовые классы iOS, но я хочу добавить некоторые функции к этому классу. Многие из этих категорий objective-c не добавляют свойства, используя objc_SetAssociatedObject. В тех случаях я использую статический вспомогательный класс в Java. Рассмотрим пример с использованием NSString и String. Я добавлю функциональность для добавления цитат в строку. Мы предположим, что это полезно и не существует для целей иллюстрации. В objective-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);
        }
    }
}

Также нет именных столкновений с исходным классом, что было бы более полезным. Названия имен в категориях objective-c считаются плохими.

Ответ 3

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

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