【问题标题】:Difference between self and super自我和超级之间的区别
【发布时间】:2012-06-02 18:02:41
【问题描述】:

刚刚有一个菜鸟问题。我试图理解调用 self 和 super 之间的区别。现在我了解了继承和其他基本 OOP 概念,但是我仍然不清楚 self 和 super 的概念。我会用一个例子来说明我的问题。

因此,当手机倒置时,以下代码会执行转场。我知道“Scene2ViewController”是“UIViewController”的子类,所以“Scene2ViewController”继承了 UIViewController 的所有方法。所以下面我调用了 performSegueWithIdentifier 方法,消息的接收者是 self。现在,当我将“self”更改为“super”时,代码仍然以相同的方式执行。调用 super 和调用 self 不一样吗?如果有人可以向我解释这一点,将不胜感激,谢谢。

//Scene2ViewController.m
- (BOOL)shouldAutorotateToInterfaceOrientation:  (UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
    [self performSegueWithIdentifier:@"SegueToScene1" sender:self];
}

return (interfaceOrientation == 
        UIInterfaceOrientationPortrait);
}

【问题讨论】:

    标签: iphone objective-c ios ipad inheritance


    【解决方案1】:

    selfsuper 实际上都指向同一个对象。 super 是一个关键字,它告诉编译器生成开始在超类而不是当前类中搜索方法定义的指令。

    @interface A : NSObject {}
    - (void)foo;
    @end
    
    @implementation A
    - (void)foo {
        NSLog(@"A's foo!");
    }
    @end
    
    @interface B : A
    @end
    
    @implementation B
    - (void)foo {
        NSLog(@"B's foo!");
    }
    @end
    
    //...somewhere in a method of class B...
    [self foo];    // prints "B's foo" in the console
    [super foo];    // prints "A's foo" in the console
    

    如果我们根据注释假设最后几行在 B 的某个方法中,那么 self 指向 B 的某个实例。super 也指向 B 的同一个实例。但是当您使用self 调用foo,搜索foo 的实现从B 类开始。使用super 时,搜索foo 从B 的超类A 开始。

    super 在您想要保留继承的行为但添加一些东西时特别方便。因此,我们可以让 B 的 foo 使用 [super foo] 调用 A 的版本。如果没有super,就无法调用继承的方法,而从被覆盖的方法中调用foo会导致无限递归。

    【讨论】:

    • 只是出于好奇,是否可以调用超级的超级?例如,如果有一个 ClassC(B 的子类),并且 ClassC 想调用 classA 的 foo 而不是 ClassB 的 foo。
    • 没有。除非您想开始使用运行时玩游戏,否则没有任何便利。我想大多数人都会同意,如果您需要这样做,那么您的设计可能有问题。
    【解决方案2】:

    当您调用self 的方法(或者更确切地说,用Objective-C 术语向self 发送消息)时,运行时将在继承层次结构中搜索该方法的实现,从self 开始,继续高达NSObject。所以如果self 实现了那个方法,它就会被执行。如果没有,super 类将被检查,依此类推。

    将消息发送到super 非常相似,只是运行时将开始在super 中寻找实现并跳过self

    【讨论】:

      【解决方案3】:

      有时候,在子类中,您可能会覆盖已在父类中定义的函数。这经常发生在 init 函数中。所以如果你需要调用父类的init函数你调用super。如果您需要子类的功能,您可以调用 self.如果只有父级声明了函数,则 Self 和 super 行为相同。但是如果只有子类有声明,那么你不能从 super 调用函数。

      【讨论】:

        猜你喜欢
        • 2016-06-21
        • 1970-01-01
        • 1970-01-01
        • 2010-12-28
        • 2012-05-07
        • 2012-08-15
        • 2011-05-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多