self与super区别:

一:self与super定义:

self:类似java中的this,表示当前接收消息的指针。(消息的接收者);

super:OC中编译预指令,没有特别指代的对象。

(注意,super并不表示self的父类,只是编译器的一个指令)

 

二:self与super的区别

1):理解:

我们都知道,OC中方法的调用,本质上是在OC Runtime期间发送消息。

[self eat]会替换成objc_msgSend(self, @selector(eat));

[super eat]会替换成objc_msgSendSuper(self, @selector(eat));

由上述可以看出,self与super在方法调用上消息接收者,消息选择子都是一样的,只是消息传递(查找消息)的机制不一样。

objc_msgSend:首先在当前实例对象的方法列表中找,若找不到,则按照继承体系,向父类,父类的父类等的方法列表中找;

objc_msgSendSuper:首先在当前实例对象的父类的方法列表中找,若找不到,则按照继承体系,向父类的父类等的方法列表中找;

2)释例说明:

Person(父类):

- (instancetype)init {

    self = [super init];

    if (self) {

        self.name = @"person name";

    }

    return self;

}

- (void)say {

    NSLog(@"I'm a Person, My name is %@",self.name);

}

Boy(子类):

- (instancetype)init {

    self = [super init];

    if (self) {

        self.name = @"boy name";

    }

    return self;

}

- (void)say {

    NSLog(@"I'm a Boy, My name is %@",self.name);

}

- (void)test {

    [self say];

    [super say];

}

我们在Boy中的执行[boy test],最终得到的输出为:

I'm a Boy, My name is boy name

I'm a Person, My name is boy name

解释:

[self say]替换objc_msgSend(self, @selector(say)),[super say]替换objc_msgSendSuper(self, @selector(say)),因为消息接收者均为self,所以self.name均为查找当前实例对象的name(self.name的输出均为boy name);但是因为查找机制不同,objc_msgSend从当前实例对象的方法列表中找(输出:I'm a Boy, My name is xxx),objc_msgSendSuper从父类的方法列表中查找(输出:I'm a Person, My name is xxx)

3):结论

在调用方法时,使用self与使用super,只是在查找方法的查找机制上有区别(self开始从当前对象的方法列表中找,而super开始从父类的方法列表中查找),其他的(包括消息接收者,消息)均相同。([self class]与[super class]的输出相同,根源在于子类,父类中均未实现class方法,调用的均是NSObject的class方法;消息接收者,查找的消息,消息参数均一样,所以输出也一样)

在NSObject中:

- (Class)class {

    return object_getClass(self);

}

### Python 中 `self` 和 `super()` 的区别 #### 自定义类中的 `self` 在 Python 面向对象编程中,`self` 是指向实例本身的引用。每当创建一个新方法时,默认第一个参数总是 `self`,这表示该方法属于特定的对象实例而不是整个类。 ```python class MyClass: def __init__(self, value): self.value = value # 使用 self 来访问属性 def show_value(self): print(f"The value is {self.value}") # 访问当前实例的数据成员 ``` 通过上述代码可以观察到,在类的方法内部使用 `self` 可以操作和修改实例变量以及调用其他实例方法[^1]。 #### 继承结构下的 `super()` 当涉及到多级继承体系时,`super()` 函数变得尤为重要。它允许子类调用父类(超类)的一个或多个实现而无需显式命名这些基类的名字。这种方式不仅提高了可维护性和灵活性,而且有助于解决复杂的多重继承场景下可能出现的问题。 考虑下面的例子: ```python class Animal: def __init__(self, species): self.species = species def speak(self): pass class Dog(Animal): def __init__(self, name): super().__init__('Canine') # 调用了父类的构造函数并传递了 'Canine' 参数给物种属性 self.name = name def bark(self): print(f"{self.name}: Woof!") dog_instance = Dog('Buddy') print(dog_instance.species) # 输出: Canine dog_instance.bark() ``` 在这个例子中可以看到如何利用 `super()` 方法来初始化父类部分的状态而不必关心具体的父类名称是什么。这样做使得代码更加简洁明了,并且如果将来改变了继承关系,则不需要更改所有涉及的地方[^2]。 #### 关键差异总结 - **作用范围不同**:`self` 主要用于指代当前实例;而 `super()` 则是用来获取最近一层父类的相关信息。 - **应用场景有别**:通常情况下,`self` 更多地出现在简单类设计里;相反地,在处理复杂层次化的类架构尤其是存在重载同名方法的情形下推荐采用 `super()` 方式来进行协作开发。 - **语法形式各异**:前者作为默认的第一个形参存在于每一个实例方法签名之中;后者则是一个内置函数,需配合圆括号调用来指定其行为目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值