self和super 详解

本文详细解析了 Objective-C 编程语言中 self 和 super 的工作原理及使用方式,通过具体示例展示了如何利用这两个关键字实现方法调用,并解释了它们之间的区别。

@interface Person:NSObject

 { 

    NSString* name; 

 } 

- (void) setName:(NSString*) yourName; 

@end


 @interface PersonMe:Person

 {

 NSUInteger age; 

}

 - (void) setAge:(NSUInteger) age; 

- (void) setName:(NSString*) yourName andAge:(NSUInteger) age; 

@end


 @implementation PersonMe

 - (void) setName:(NSString*) yourName andAge:(NSUInteger) age { 

[self setAge:age]; 

[super setName:yourName]; 

@end

 int main(int argc, char* argv[]) 

{

 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; PersonMe* me = [[PersonMe alloc] init]; 

[me setName:@"asdf" andAge:18];

 [me release]; 

[pool drain]; return 0;

 }

self是类的隐藏的参数,指的是当前调用方法的类,另外一个隐藏参数是 _cmd,代表当前类方法的selector。

super并不是隐藏参数,它是一个“编辑器指示符”,它和self指向给的是相同的消息接受者

如上面的代码

[self setAge:age]; 

[super setName:yourName]; 

不论是哪个,接收“setName”这个消息的接受者都是PersonMe* me 这个对象,不同的是super告诉编译器,当调用setName这个方法时,要去调用父类的方法,而不是在本类里。

当使用self调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找,

而当使用super时,则直接从父类的方法列表中开始找,然后调用父类的这个方法

在 Python 中,`self` 是一个约定俗成的参数名,主要用于在类的方法中引用类的实例对象本身。当创建类的实例后,通过实例调用类的方法时,Python 会自动将实例对象作为第一个参数传递给方法,这个参数在方法定义中通常被命名为 `self`。以下结合给定代码详细解释 `self` 的含义作用。 ### `self` 在 `Bike` 类中的作用 ```python class Bike: total_bikes = 0 def __init__(self, bike_id, brand, base_rate): self.bike_id = bike_id self.brand = brand self.base_rate = base_rate Bike.total_bikes += 1 def rent(self, duration): if duration <= 0: raise ValueError("租借时长必须大于 0 小时。") return self.base_rate * duration def __str__(self): return f"[普通自行车] 编号: {self.bike_id}, 品牌: {self.brand}, 基础费率: {self.base_rate} 元/小时" ``` - **`__init__` 方法**:在类的构造函数 `__init__` 中,`self` 用于将传入的参数赋值给实例的属性。例如,`self.bike_id = bike_id` 表示将传入的 `bike_id` 参数值赋给当前实例的 `bike_id` 属性。这样,每个实例都有自己独立的 `bike_id`、`brand` `base_rate` 属性。 - **`rent` 方法**:在 `rent` 方法中,`self.base_rate` 用于访问当前实例的 `base_rate` 属性。因为不同的 `Bike` 实例可能有不同的 `base_rate`,所以通过 `self` 可以确保使用的是当前实例的属性值。 - **`__str__` 方法**:在 `__str__` 方法中,`self.bike_id`、`self.brand` `self.base_rate` 同样用于访问当前实例的属性,以便返回一个包含实例信息的字符串。 ### `self` 在 `Ebike` 类中的作用 ```python class Ebike(Bike): def __init__(self, bike_id, brand, base_rate, battery_level, extra_rate): super().__init__(bike_id, brand, base_rate) self.battery_level = battery_level self.extra_rate = extra_rate def rent(self, duration): if self.battery_level < 20: raise LowBatteryError(self.bike_id, self.battery_level) cost = super().rent(duration) + self.extra_rate * duration # 电量消耗:每小时 15% self.battery_level = max(0, self.battery_level - duration * 15) return cost def __str__(self): return ( f"[电动自行车] 编号: {self.bike_id}, 品牌: {self.brand}, " f"基础费率: {self.base_rate} 元/小时, 附加费率: {self.extra_rate} 元/小时, " f"当前电量: {self.battery_level}%" ) ``` - **`__init__` 方法**:在 `Ebike` 类的构造函数中,`super().__init__(bike_id, brand, base_rate)` 调用了父类 `Bike` 的构造函数,初始化了 `bike_id`、`brand` `base_rate` 属性。然后,`self.battery_level = battery_level` `self.extra_rate = extra_rate` 为 `Ebike` 实例添加了自己特有的 `battery_level` `extra_rate` 属性。 - **`rent` 方法**:在 `rent` 方法中,`self.battery_level` 用于检查当前实例的电量是否低于 20%。如果低于 20%,则抛出 `LowBatteryError` 异常。`self.extra_rate` 用于计算附加费用。同时,`self.battery_level = max(0, self.battery_level - duration * 15)` 更新了当前实例的电量属性。 - **`__str__` 方法**:在 `__str__` 方法中,`self.bike_id`、`self.brand`、`self.base_rate`、`self.extra_rate` `self.battery_level` 用于访问当前实例的属性,返回一个包含电动自行车信息的字符串。 ### `self` 在 `BikeRentalSystem` 类中的作用 ```python class BikeRentalSystem: all_bikes = [] _id_counter = 0 def __init__(self): self.rental_records = [] @staticmethod def generate_bike_id(): BikeRentalSystem._id_counter += 1 return f"BK-{BikeRentalSystem._id_counter:04d}" @classmethod def register_bike(cls, bike): cls.all_bikes.append(bike) def rent_bike(self, bike_id, duration): bike = next((b for b in self.all_bikes if b.bike_id == bike_id), None) if not bike: raise LookupError(f"未找到编号为 {bike_id} 的车辆。") cost = bike.rent(duration) record = { "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "bike_id": bike_id, "duration": duration, "cost": cost, "type": bike.__class__.__name__, } self.rental_records.append(record) return cost, record ``` - **`__init__` 方法**:在 `BikeRentalSystem` 类的构造函数中,`self.rental_records = []` 为每个 `BikeRentalSystem` 实例创建了一个独立的 `rental_records` 列表,用于存储租赁记录。 - **`rent_bike` 方法**:在 `rent_bike` 方法中,`self.all_bikes` 用于访问当前 `BikeRentalSystem` 实例的 `all_bikes` 列表,查找指定 `bike_id` 的自行车。`self.rental_records.append(record)` 将租赁记录添加到当前实例的 `rental_records` 列表中。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值