在继承中,子类拥有父类所有的属性和方法,可以直接使用父类中已经封装好的方法,但如果父类中的方法不能满足子类需求,就要在子类中对方法进行重写。
如果子类与父类的方法和属性名相同,则在使用子类对象进行调用时,默认调用的是子类中定义的属性和方法。
方法重写分为两种情况:
1、覆盖父类的方法
父类与子类的方法实现完全不同,可以使用覆盖的方式,就是在子类中重新编写父类的方法实现。相当于在子类中定义了一个和父类同名的方法并实现。
重写之后,在使用子类对象调用方法时,只会调用子类中重写的方法,而不会调用父类中封装的方法。
class Pig:
def hobby(self):
print('小猪喜欢吃东西和睡觉')
class Peppa(Pig): # Peppa类继承自Pig类
def hobby(self):
print('佩奇最喜欢跳泥坑')
pig = Pig()
# 父类的hobby方法
pig.hobby() # 小猪喜欢吃东西和睡觉
peppa = Peppa()
# 子类Peppa对父类Pig中的hobby方法进行了重写,所以调用的是子类Peppa的hobby方法
peppa.hobby() # 佩奇最喜欢跳泥坑
2、对父类的方法进行扩展
如果父类原本封装的方法实现是子类方法的一部分(子类方法的实现包含父类的方法实现),就可以使用扩展的方式来实现:在需要的位置使用
覆盖是在子类中对父类的方法实现完全修改了,扩展是在子类中对父类的方法实现增加了一些功能。
class Pig:
def hobby(self):
print('小猪喜欢吃东西和睡觉')
class Peppa(Pig): # 子类
def hobby(self): # 对父类的hobby方法进行扩展
# 针对子类的需求,编写子类特有的
print('我是小猪佩奇。')
# 使用super().父类方法,调用原本在父类中封装的方法
super().hobby()
print('佩奇最喜欢跳泥坑')
pig = Pig()
# 父类的hobby方法
pig.hobby() # 小猪喜欢吃东西和睡觉
peppa = Peppa()
# 子类Peppa对父类Pig中的hobby方法进行了重写,所以调用的是子类Peppa的hobby方法
peppa.hobby() # 佩奇最喜欢跳泥坑
这里涉及一个 super,下面介绍一下:
调用父类的方法 —— super类
super 是 Python 中的一个特殊的类。super() 就是实例化了一个 super 类,就像一个 Person 类,使用 “Person()” 实例化一个对象。
它通常用于在重写父类方法时,调用在父类中封装的方法实现。
调用方法:super(子类名,self).方法名(参数1,参数2……)。其中 子类名,self 这两个参数可以省略。
语法格式:
# 1、有参数
super(当前子类名,self).方法名(参数1,参数2……)
# 2、省略参数
super().方法名(参数1,参数2……)
子类必须在其构造函数中调用父类的构造函数
如果父类定义了 __init__() 方法,而子类没有定义,则默认子类继承父类的 __init__() 方法。如果子类也定义了 __init__() 方法,那就是子类重写了父类的 __init__() 方法。一般就是对父类 __init__() 方法进行扩展,所以在子类的构造函数中,要调用父类的构造函数 __init__()。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def printInfo(self):
print(f'我的名字叫{self.name},今年{self.age}岁。')
class Student(Person):
# 子类必须在其构造函数中调用父类的构造函数
def __init__(self, name, age, stu_id):
super().__init__(name, age) # 调用父类的__init__()方法
self.stu_id = stu_id # 增加子类特有的属性
def printInfo(self): # 父类的printInfo方法不能满足子类的需求,所以对方法进行重写扩展
# super(子类名,self).方法名(参数1,参数2……)。其中 子类名,self 这两个参数可以省略。
super().printInfo()
print(f'我的学号是{self.stu_id}')
class Teacher(Person):
# 父类Person定义了__init__()方法,子类需显式调用父类的__init__方法
def __init__(self, name, age, teacher_yaear):
# super(子类名,self).方法名(参数1,参数2……)。其中 子类名,self 这两个参数可以省略。
# super(Teacher,self).__init__(name, age) # 调用父类的__init__()方法
super().__init__(name, age) # 调用父类的__init__()方法
self.teacher_yaear = teacher_yaear # 增加子类特有的属性
def printInfo(self): # 父类的printInfo方法不能满足子类的需求,所以对方法进行重写扩展
print(f'我的名字叫{self.name},今年{self.age}岁,我的教龄是{self.teacher_yaear}')
stu = Student('张三', 21, '123456')
tea = Teacher('李老师', 45, 15)
stu.printInfo()
tea.printInfo()
调用父类的方法还可以通过 父类名.方法(self) 。但是这种方法不推荐使用,因为如果父类一旦发生变化,方法调用处的类名也需要修改。注意这里的类名不能写错,如果写成了当前子类名,会导致递归调用,形成死循环。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def printInfo(self):
print(f'我的名字叫{self.name},今年{self.age}岁。')
class Student(Person):
# 子类必须在其构造函数中调用父类的构造函数
def __init__(self, name, age, stu_id):
Person.__init__(self,name,age) # 通过 父类名.方法(self) 的方式调用父类的__init__()方法
self.stu_id = stu_id # 增加子类特有的属性
def printInfo(self): # 父类的printInfo方法不能满足子类的需求,所以对方法进行重写扩展
Person.printInfo(self)
print(f'我的学号是{self.stu_id}')
stu = Student('张三', 21, '123456')
stu.printInfo()
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报。
3 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
暂无评论内容