代码之家  ›  专栏  ›  技术社区  ›  pilsetnieks

Objective-C中的子类化是一种糟糕的做法吗?

  •  16
  • pilsetnieks  · 技术社区  · 7 年前

    在阅读了大量的博客、论坛条目和一些苹果文档之后, 我仍然不知道在Objective-C中扩展子类化是否是明智之举 .

    假设我正在开发一款益智游戏 元素共享一定数量的 同样的行为。然后,在我的 元素集合,不同 元素组共享相同的值 行为,区分群体和 团体等等。。。

    那么,在确定继承什么之后 从什么来的, 我决定把它分类 遗忘。为什么我不能呢? 我认为,这种模式的行为很重要

    但是,-这就是我的问题的来源-苹果提到 . 我真的很奇怪为什么?

    我想知道大规模子类化和不大规模子类化的优缺点是什么 ?

    总而言之,我的问题很简单:

    9 回复  |  直到 17 年前
        1
  •  12
  •   Kendall Helmstetter Gelner    17 年前

    委托是一种使用组合技术来替换编码的某些方面的方法,否则您将为其创建子类。因此,它归结为一个由来已久的问题,即手头的任务需要一件知道如何做很多事情的大事情,或者您是否有一个松散的专门对象网络(一种非常UNIX的责任模型)。

    使用委托和协议的组合(定义委托应该能够做什么)提供了很大的行为灵活性和编码的便利性——回到Liskov替换原则,当您创建子类时,您必须小心,不要做整个类的用户会发现意外的事。但是,如果您只是简单地创建一个委托对象,那么您所要负责的事情就少了很多,只是您实现的委托方法实现了一个协议所要求的功能,除此之外,您并不关心。

    使用子类仍然有很多很好的理由,如果您确实在许多类之间拥有共享的行为和变量,那么使用子类可能非常有意义。但是,如果您能够利用委托概念,通常会使您的类更易于扩展或以设计者可能没有预料到的方式使用。

    与非正式协议相比,我更喜欢正式协议,因为正式协议不仅确保您拥有一个类将您视为委托所期望的方法,而且还因为协议定义是记录您期望从实现这些方法的委托获得什么的自然场所。

        2
  •  10
  •   Martin Cote    17 年前

    就我个人而言,我遵循这个规则:如果子类尊重 Liskov substitution principle .

        3
  •  7
  •   Bryan Kyle    17 年前

    子类化有其优点,但也有一些缺点。一般来说,我尽量避免实现继承,而是使用接口继承和委托。

    其他人提到了利斯科夫替代原则。我认为使用它肯定会解决java.util.Stack问题,但它也会导致非常深层的类层次结构,以确保类只获得它们应该拥有的方法。

    但最终,你走哪条路并不重要。两者都是完全可以接受的。实际上,这更多的是一个问题,即您对什么更满意,以及您使用的框架鼓励了什么。俗话说:“入乡随俗。”

        4
  •  6
  •   Don McCaughey    17 年前

    在Objective-C中使用继承并没有什么错。苹果经常使用它。例如,在Cocoa touch中,UIButton的继承树是UIControl:UIView:UIResponder:NSObject。

    我认为马丁在提到利斯科夫替换原则时抓住了一个重要的要点。此外,正确使用继承要求子类的实现者对超类有深入的了解。如果您曾经在复杂的框架中努力扩展一个非平凡的类,那么您知道总会有一条学习曲线。此外,超类的实现细节往往会"泄漏"到子类,这是@$& ;;对于框架构建者。

    苹果公司在许多情况下选择使用授权来解决这些问题;像UIApplication这样的非平凡类通过委托对象公开公共扩展点,因此大多数开发人员都有一个更简单的学习曲线和一种更松散耦合的方式来添加特定于应用程序的行为——直接扩展UIApplication几乎不必。

    在您的情况下,对于特定于应用程序的代码,请使用您熟悉并最适合您的设计的技术。如果使用得当,继承是一个很好的工具。

        5
  •  4
  •   olliej    17 年前

    通常,如果存在完成您想要做的事情的委托等,您应该避免子类化API类。在您自己的代码中,子类化通常更好,但它确实取决于您的目标,例如,如果您提供的是API,那么您应该提供基于委托的API,而不是假设子类化。

    在处理API时,子类化有更多潜在的bug——例如,如果类层次结构中的任何类得到了一个新方法,该方法与您添加的方法同名,那么您就创建了break。而且,如果您提供了一个有用的/helper类型函数,那么将来有可能会在您正在子类化的实际类中添加类似的内容,这可能会更有效,等等,但是您的重写将隐藏它。

        6
  •  4
  •   DragoRaptor    13 年前

    请阅读苹果的文档 "Adding behavior to a Cocoa program" !. 在下面 第二节,见第二段。Apple明确提到子类化是将特定于应用程序的行为添加到框架中的主要方式(请注意, 框架 ).
    作为一名开发人员,必须注意实现是有良好文档记录的,并且不会被其他开发人员意外复制。如果您的应用程序是一组您计划作为可重用组件分发的API类,那就完全是另一回事了。

    IMHO首先要彻底阅读相关文档,实施并测试它,而不是四处询问最佳实践是什么。做出你自己的判断。你最清楚自己在干什么。 对于其他人(像我和其他很多人)来说,在网上阅读来自不同来源的内容并随意使用术语是很容易的。做你自己的裁判吧,到目前为止,这对我很有效。

        7
  •  3
  •   Tim    17 年前

    我真的认为这取决于你想做什么。如果您在示例中描述的益智游戏确实有一组共享公共属性的独特元素,并且没有提供适合您需要的类(例如,“NSPuzzlePiece”),那么我认为广泛地子类化没有问题。

    根据我的经验,如果Apple提供了一个类,该类已经做了一些接近您希望它做的事情,那么委托、数据源方法和非正式协议就更有用了。

        8
  •  2
  •   kent    17 年前

    话虽如此,我对ADC强调子类化的印象是 而是 新的做事方式

    所以,无论如何,尽可能稳健地设计拼图程序的架构,利用您认为合适的继承性!

    期待看到你的酷新益智应用程序!

    |K<

        9
  •  0
  •   Patrick Waugh    12 年前

    苹果似乎确实消极地不鼓励使用Objective-C进行子类化。