Java可以在Objective C中做类似category的事情吗?
请考虑以下情况:
Object > MyClass > MyClassA, MyClassB
例如,如果我想要在对象级别中有所作为,我添加了printDetail();如何在Java实现中做到这一点?此外,我可以重写所有对象的方法吗?例如,我需要有一个全新的.toString(),我可以覆盖它吗?谢谢。
请考虑以下情况:
Object > MyClass > MyClassA, MyClassB
例如,如果我想要在对象级别中有所作为,我添加了printDetail();如何在Java实现中做到这一点?此外,我可以重写所有对象的方法吗?例如,我需要有一个全新的.toString(),我可以覆盖它吗?谢谢。
不,它不能,反正不是真的。Objective C是一种动态类型化和作用域化的语言,这使得它非常适合类别等功能。在Java中,最接近这一点的是通过字节代码操作库(如ASM或Javassist)进行类检测。
但实际上,当使用像Java这样的强类型OO语言时,你应该接受它的功能,而不是试图复制另一种语言的功能。
正如其他答案中提到的,没有什么比类别更像了。在移植到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
你可以从这样的地方调用它:
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类别中的名称冲突被认为是不好的。