2012-03-14 33 views
16

请考虑以下情况:Java可以在Objective C中做类似的事情吗?

Object > MyClass > MyClassA, MyClassB 

如果我要在对象层次的东西,比如我加printDetail();我如何在Java实现中实现它?此外,我可以重写所有对象的方法。例如,我需要一个全新的.toString(),我可以覆盖它吗?谢谢。

回答

28

不,它不能,不是真的。 Objective C是一种动态类型和范围的语言,它非常适用于类别等功能。在Java中最接近这一点的是通过类似ASMJavassist这样的字节代码操作库的类仪器。

但实际上,当使用像Java这样的强类型OO语言时,应该拥抱它的特性,而不是试图复制另一种语言的特性。

+0

很好的答案..! – 2013-07-31 18:02:05

+0

虽然评论有些学术性,但我认为问题在于因素:例如,如果我想要一种方法来随机化数组中的事物顺序,我可能会说:“从语义上讲,这是我要求数组执行的一种行为;因此,我会将其作为数组中的一种方法进行语法添加”。我认为这不会削弱强类型或面向对象。但是,不,这不是Javaish。 – Tommy 2015-05-14 19:57:55

+1

C#不是强类型的OO语言吗?因为C#通过扩展方法提供了这种能力。从其他语言获得好东西有什么不好?这是一种进步...... – obe 2015-12-17 21:58:22

2

所有Java类最终都有java.lang.Object正因为如此,所有Java classes inherit方法从Object。这些方法中有一半是final,不能是overridden。但是,Object中的其他方法可以被重写
Object类中的toString()方法用于显示有关任何对象的某些信息。
所以,你可以根据你自己重写吧...
EX ..

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

我明白了。我使用红宝石,允许我重写顶级对象。 – DNB5brims 2012-03-14 07:22:04

11

正如在其他的答案中提到,没有什么真像一个类别。移植到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); 

如果您将类别方法看作自动发送自变量作为第一个方法参数的方法(虽然不可见),那么这更有意义。

对于你的榜样,如果我不会扩大特定对象,我可能会做这样的事情:

public class ObjectHelper { 

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

UPDATE:一个评论者要求的限制。

限制条件是该代码位于单独的静态类中。这不像一个类别那么方便。您必须记住这些类名,或者找到它们,并且您不会在助手中的原始对象方法上自动完成。此外,您不能使用像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); 
     } 
    } 
} 

也没有与原始类名称冲突,这将是更多的好处。目标-c类别中的名称冲突被认为是不好的。

+0

我最喜欢这个答案,因为它给了我一个解决方法。谢谢! – 2015-07-07 02:31:24

+0

@ptoinson如果我们将这种方式与iOS中的类别进行比较,什么是限制? – NghiaDao 2016-12-05 08:07:05

+0

@NghiaDao - 添加到答案更新的限制。 – ptoinson 2016-12-06 19:21:30

相关问题