理解子类中的__init__()和super()函数的困惑
理解子类中的__init__()和super()函数的困惑
我对Python中的这两个特定概念有点困惑。我觉得我大致上理解了它们,但还没有完全理解。
根据我的了解,super()调用父类的init方法,并处理从父类传递给它的参数。
那么为什么子类中需要有一个包含与超类中相同参数的init方法呢?是因为两个类在本质上仍然相似,因此子类需要一些超类的基本特性吗?我知道大多数类都需要一个构造函数,只是想知道为什么你需要在子类构造函数中重新定义与超类中相同的参数,并在该构造函数的主体中使用super()函数。
一个代码示例可能是这样的:
# 9-6 冰淇淋店
class Restaurant:
def __init__(self, restaurant_name, cuisine_type):
"""设置餐馆的属性"""
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
self.number_served = 0
def describe_restaurant(self):
"""打印关于餐馆的声明"""
print(f"欢迎来到{self.restaurant_name.title()}!享受我们美味的{self.cuisine_type.title()}美食吧!")
def open_restaurant(self):
"""打印餐馆开门的消息"""
print(f"{self.restaurant_name.title()}正在营业,欢迎光临!")
def set_number_served(self, total_served):
self.number_served = total_served
def increment_number_served(self, additional_served):
self.number_served += additional_served
class IceCreamStand(Restaurant):
def __init__(self, restaurant_name, cuisine_type='冰淇淋'):#与超类构造函数中相同的参数
"""初始化父类的属性,然后初始化特定于冰淇淋店的属性。"""
super().__init__(restaurant_name, cuisine_type)
self.flavors = []
def display_flavors(self):
"""显示冰淇淋口味"""
for flavor in self.flavors:
print(f"- " + f"{flavor}")
ic_stand1 = IceCreamStand('美味冰淇淋')
ic_stand1.flavors = ['巧克力', '香草', '草莓']
ic_stand1.display_flavors()
ic_stand1.describe_restaurant()
有人可以友善地给我解释一下这个代码吗?这样我就能更清楚地理解这些概念了。感谢所有的帮助。
通过阅读上述内容,我们可以总结出问题的出现原因和解决方法。
问题的出现原因是,在子类IceCreamStand
的__init__()
方法中,没有指定餐厅的名字,而只是默认了菜系类型为冰淇淋。这样的设计不合理,因为它允许调用者传入不符合逻辑的菜系类型。
解决方法是,在IceCreamStand
的__init__()
方法中,使用super().__init__()
调用父类Restaurant
的__init__()
方法,并传入餐厅的名字和固定的菜系类型(冰淇淋)作为参数。这样可以确保子类IceCreamStand
在构造时会先构造父类Restaurant
,并初始化相关属性。
下面是整理后的文章:
在子类的__init__()
方法中,通常会调用父类的__init__()
方法来初始化父类的属性。然而,有时候子类的__init__()
方法需要额外的参数,而这些参数又无法通过父类的__init__()
方法来传递。这时候就需要使用super()
函数来解决这个问题。
在上述例子中,子类IceCreamStand
继承自父类Restaurant
,并且有自己的__init__()
方法。问题出现在子类的__init__()
方法中,它没有指定餐厅的名字,而只是默认了菜系类型为冰淇淋。这样的设计不合理,因为它允许调用者传入不符合逻辑的菜系类型。
为了解决这个问题,我们可以在IceCreamStand
的__init__()
方法中使用super().__init__()
来调用父类Restaurant
的__init__()
方法,并传入餐厅的名字和固定的菜系类型(冰淇淋)作为参数。这样可以确保子类在构造时会先构造父类,并初始化相关属性。
下面是修改后的代码示例:
class IceCreamStand(Restaurant): def __init__(self, restaurant_name): """Initialize the attributes of the parent class Then initialize the attributes specific to an ice cream stand.""" super().__init__(restaurant_name, 'ice cream') # The `cuisine_type` is always ice cream now self.flavors = [] # ...