Java可以在Objective C中做类似的事情吗?

DNB*_*ims 18 java objective-c-category

考虑以下情况:

Object > MyClass > MyClassA, MyClassB
Run Code Online (Sandbox Code Playgroud)

例如,如果我想要对象级别的东西,我添加了printDetail(); 我怎样才能在Java实现中做到这一点?此外,我可以覆盖所有Object的方法.例如,我需要一个全新的.toString(),我可以覆盖它吗?谢谢.

Per*_*ion 28

不,它不能,不管怎么说.Objective C是一种动态类型和范围的语言,它使得它非常适合像类别这样的功能.Java中最接近的是通过字节码操作库(如ASM或Javassist)进行类检测.

但实际上,当使用类似Java的强类型OO语言时,你应该接受它的功能,而不是试图复制另一种语言的功能.

  • C#不是强类型的OO语言吗?因为C#通过扩展方法提供此功能.从其他语言中获取好东西有什么问题?这是进步的一种方式...... (2认同)

pto*_*son 12

正如其他答案中所提到的,没有什么比一个类别更像.在移植到java时,我确实有一些常用的解决方案,用于我的objective-c代码中的某些类别.我存在许多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
Run Code Online (Sandbox Code Playgroud)

你会从这样的地方叫这个:

NSString *myString = @"When you're curious, you find lots of interesting things to do.";
NSString *quotedString = [myString quotedString];
Run Code Online (Sandbox Code Playgroud)

以下是我将如何在Java中实现它:

public class StringHelper {

    public static String quotedString(String that) {
        return '"' + that + '"';
    }
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

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

如果您将类别方法视为自动将自变量作为第一个方法参数发送的方法(尽管是不可见的),那么这就更有意义了.

对于您的示例,如果我不扩展特定对象,我可能会执行以下操作:

public class ObjectHelper {

    public static void printDetail(Object that) {
        // do what it takes;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:一位评论者要求限制.

限制是代码在一个单独的静态类中.它不像一个类别那么方便.您必须记住这些类名,或者找到它们,并且您将无法在帮助程序中对原始对象方法进行自动完成.此外,您不能使用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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

原始类别也没有名称冲突,这将更有利.Objective-c类别中的名称冲突被认为是不好的.