2011-08-10 51 views
12

如果一个方法是在两个一类和该类的类定义的,它是未定义的,其执行将被调用。目标C类和继承

但这是如何与继承交互?具体来说:

  • 给定子类中的超类别方法和常规方法,是否保证在子类的成员上调用子类实现会获胜?
  • 给定一个超常规的方法和子类中的方法试图将其覆盖,能够保证所有的子类中的一员对调用的时候,子类实现赢?
  • 给定一个超类中的方法和子类分类方法,能够保证所有的子类中的成员在调用的时候,子类中的方法将胜出?
+0

我不会说 '没办法'。您可以在类别+加载方法中拦截原始实现并获得一些乐趣;) –

+3

如果某个类别覆盖该类别中存在的方法,则将调用该类别方法。当同一类中的两个类别实现/覆盖相同的方法时,会出现冲突。这很重要,因为很多Cocoa类的方法都是在类别中实现的。如果你试图覆盖一个框架定义的方法,它可能已经在一个类中实现,而哪个实现优先是* undefined *。 – albertamg

回答

49

就让我们把这种方式。不要用类别,句点,回答结束来覆盖方法。

+2

太糟糕了,我今天没有投票赞成这个。 –

+0

我认为人们喜欢理性,而不是盲目的建议 – onmyway133

+0

@entropy:在问这个问题数百次后,Joshuas的答案完全符合需要。类别不是继承和子类化的工具。 – vikingosegundo

40

如果在该类的类和类别中都定义了一个方法,则 未定义将调用哪个实现。

这是不正确;类别方法将永远赢。什么都不行,虽然是如果你有实现相同的方法多个类别,那么“哪一个赢”是不确定的。

它通常是“最后加载胜”,但真的不是一个硬性的规则,无论是。

注意,因为很多类会在内部有跨类别的执行划分为代码组织的目的,你可以不依赖于第一条规则反正。

总之,约书亚说。 请勿使用类别覆盖方法。

除了继承的原因,你也恶毒破坏了封装,当你这样做。这不是基于类别的实现覆盖现有的方法,而是完全取代它。因此,如果你不重现每一个最后的内部实现细节,包括错误,换货不会很工作的权利和调试这将是

+1

那么,这是我的问题的一部分。超类(UIView)是一个Apple类。我有一个类添加了一个方法;我们称之为myUIViewCategoryMethod。如果我在子类中重写该方法,我可以确定子类版本会赢吗?如果我在一个子类上使用类别,该怎么办? –

+2

是的 - 子类实现将永远胜利。 – bbum

+0

子类化并不总是可用的,但有时需要替换或增强某个功能。在这种情况下,绝对不推荐分类覆盖。相反,使用Objective C Runtime与您想修改的方法交换您自己的方法的实现,并在适当情况下调用原始实现。 –

-1

从我测试

  1. 给定一个超类中的方法,并在 子类常规方法中,它保证了子类实现将赢得 子类的成员在调用时? =>子胜
  2. 给定一个超常规的方法和子类中的方法 试图覆盖它,是保证子类中的一员叫上当子 类别执行会胜出? => 子类类胜
  3. 给定一个超类方法和子类类中的方法,是 它保证当 子类的成员上被称为子类类方法将赢了吗?=>子类别胜

看看在Test category and subclass

+0

谈到类别重写的子类似乎是错误的,我已经。对于这个话题,他可能是堆栈溢出最有能力的人之一。 – vikingosegundo

+0

@vikingosegundo你是对的。我只是想通过一个小测试来澄清这一点。运行时添加类别方法的顺序必须与bbum所说的一样: – onmyway133

+0

许多类按类别分类。我们不知道他们加载的顺序。 – vikingosegundo