【问题标题】:Objective-C Subclassing: Do superclass methods have to be declared in the header file to be used in the subclass?Objective-C 子类化:是否必须在头文件中声明超类方法才能在子类中使用?
【发布时间】:2015-01-26 03:04:55
【问题描述】:

假设我们这个例子:

类.h:

@interface Class : NSObject

/* No public methods or ivars */

类.m:

@implementation Class

-(void)methodOne{}
-(void)methodTwo{};

子类.h:

@interface Subclass : NSObject

/* No public methods or ivars */

子类.m:

@implementation Subclass

/* I want to override methodOne and methodTwo from superclass but can't. They don't show up as methods */

您是否必须在其头文件中将超类中的方法显式声明为 public 才能使用子类中的方法?我认为实现文件中的方法只能被覆盖。

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    重写私有方法是不好的做法。私有化的全部意义在于任何人都不应该依赖它们。私有方法就是这样 - 私有的。他们的签名可能会改变,他们的实现可能会改变,或者他们可能会在未来消失。如果子类覆盖私有方法,任何此类更改都会导致子类中断。如果该方法打算被覆盖,那么它应该被公开并且 API 应该是稳定的。

    如果方法应该只被子类覆盖并且从不被基类的其他客户端调用,那么基类应该提供第二个头文件,声明一个类别中的方法,专门意味着只能由子类导入和使用。

    Apple 提供的类UIGestureRecognizer 就是一个很好的例子。有一个特殊的头文件“UIGestureRecognizerSubclass.h”,仅由子类导入。有关详细信息,请参阅UIGestureRecognizer 文档的“子类化注释”部分。

    【讨论】:

      【解决方案2】:

      您是否必须在其头文件中将超类中的方法显式声明为 public 才能使用子类中的方法?

      不,方法不必在超类头文件中声明。它们可以声明为class extension 的一部分。

      使用您的示例,这看起来像:

      @interface Class(SomeNameOrNot)
      
      -(void)methodOne{}
      -(void)methodTwo{};
      
      @end
      

      这可以通过两种方式表示:在头文件中或作为实现文件的一部分。

      因此,例如,如果 Subclass 并且只有该类需要了解这些选择器,则上述类扩展将进入 Subclass.m

      如果这些方法打算供Class 的任何子类使用,但不打算公开,它们可能会进入只有这些子类知道的头文件(即Class_Internal.h)。这是提供类似 Java 的 protected 访问权限的常用方法 - 一组接口仅适用于通过导入私有标头选择使用它的子类。

      【讨论】:

      • 将超类的扩展放在其子类之一的实现之上(超类甚至看不到它们)是非常糟糕的设计恕我直言。你要求打破的东西
      猜你喜欢
      • 2015-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      • 2019-08-14
      • 2016-06-11
      • 1970-01-01
      相关资源
      最近更新 更多