【问题标题】:Objective-C Not to override methods declared in implementationObjective-C 不覆盖实现中声明的方法
【发布时间】:2013-12-12 08:52:15
【问题描述】:

我有一个继承自 UIViewController 的类。此类提供了几个视图控制器需要实现的基本功能,因此它们将从此类继承。我不使用它直接创建任何实例的原因。

父类和子类都有一个名为setupView 的方法,该方法在每个类'viewDidLoad 中调用。两个类的方法完全相同:

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view.

    [self setupView];
}

setupView 没有在interface 中声明,它只是在implementation 中定义,但我会阻止任何其他类访问或覆盖它。但是,当父级的viewDidLoad 被其子级调用并执行[self setupView] 时,将调用子级的setupView 而不是自己的。

我有两个问题:

  1. 为什么子类可以覆盖未在接口中声明的方法?
  2. 如何防止这种情况发生?

--编辑--

每个setupView 方法都执行该视图控制器独有的配置。例如父类使用这个方法来配置每个子类需要的UIBarButtonItem,子类使用它来配置它将使用的表格视图。

我不想在子类中配置UIBarButtonItem,因为我必须在每个子类中都这样做,这正是我决定创建父类的原因。我也不想使用[super setupView],因为孩子不应该知道父类中的这个方法。

能够覆盖接口中未声明的方法,是否违反封装原则?

--回答--

Objective-C 中的任何方法都可以被覆盖,包括那些没有在interface 中声明的方法。这意味着子类中的方法必须具有不同的名称,除非打算重写该方法。

【问题讨论】:

    标签: objective-c inheritance


    【解决方案1】:

    如果一个孩子实现了与父母相同的方法,它基本上会覆盖这个方法。然后您可以使用[super methodName] 调用父方法。因此,如果您在孩子中覆盖 setupView 并且还希望调用父母的 setupView,您应该从孩子那里调用它:

    - (void)setupView
    {
        [super setupView];
        // child code
    }
    

    【讨论】:

    • 另外,您应该从子视图中删除额外的 [self setupView] 调用。把这项工作留给父母;)
    • 请检查编辑。我不想打电话给[super setupView],因为孩子不应该知道这种方法的存在。我认为一个能够覆盖或调用仅在接口中声明的方法。如果我使用框架并错误地覆盖私有方法,会不会不安全?我无法知道该方法是否真的存在,因为它没有在接口中声明。或者,是吗?这不违反封装原则吗?
    • 在这种情况下,您应该使用不同的名称,setupBarButtons 或类似的名称。因为覆盖一个方法会在该类上永久覆盖它。
    • 感谢您的解释。我不知道可以覆盖非公共方法。
    【解决方案2】:

    这是默认方法。子代覆盖父代的方法。

    我看到了两种可能的解决方案:

    • 使用不同的名称
    • 改变child的方法如下:

    .

    - (void)setupView
    {
        if([super respondsToSelector:_cmd])
            [super performSelector:_cmd];
        // child code
    }
    

    【讨论】:

    • 我认为只有在 interface 中声明的方法可以被覆盖。能做到这点不违背封装原则?
    • 没有。所有方法。这是Objective C中的多态性
    • 这不安全吗?例如,如果我使用库,我无法知道implementation 中使用了哪些方法,我只知道interface 中声明的方法。这意味着我有可能覆盖一个我什至不知道它存在的方法?
    【解决方案3】:

    您可以做的是检查该类是否是子类,然后执行您的设置视图。但不得不这样做是一件坏事。因为你的子类应该从它的父母那里继承一切

    【讨论】:

      猜你喜欢
      • 2012-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多