子类使用父类资源已经得到验证,但是子类没有办法修改父类的资源也是既定事实,这时候我们想给派生出来的子类加一些特殊的属性或方法只有一种方法了,只能加一个不一样名称的属性或者方法,但是这种写法并不环保,所以python就使用同名覆盖的处理来实现父类资源的覆盖(重写)和累加。
首先我们知道子类查找资源的时候有三种情况:链式继承,无重叠多继承,有重叠多继承。
1.覆盖(重写)
子类和父类拥有同样的属性或方法,子类的优先级高会覆盖父类的属性或方法,主要是根据继承关系来确定优先级。
class Person:
name = 'jerry'
def run(self):
print('跑起来')
class man(Person):
name = 'Tom' # 属性覆盖
# def run(self): # 方法重写
# print('跑的很快')
m = man()
print(m.name)
m.run()
返回结果:
Tom
跑起来
2.累加
在父类的基础上子类额外增加的属性或方法,或者在子类方法相对于父类同样方法进行功能扩展。累加方法主要分为:1.直接新增方法和属性,2.在父类方法上新增一些功能。
class Person:
name = 'jerry'
def __init__(self):
self.age = 19
def run(self):
print('跑起来')
@classmethod
def eat(cls):
print('吃饭啦')
@staticmethod
def sleep():
print('睡觉了')
class Man(Person):
name = 'Tom'
def __init__(self):
self.sex = 'man'
def run(self):
print('跑的很快')
@classmethod
def eat(cls):
print('吃你的吧')
@staticmethod
def sleep():
print('快点做梦')
pass
子类和子类对象可以使用父类中的所有方法:
m = Man()
m.run()
m.eat()
m.sleep()
Man.run(m) # 这里必须传入子类实例化的对象
Man.eat()
Man.sleep()
返回结果:
跑的很快
吃你的吧
快点做梦
跑的很快
吃你的吧
快点做梦
如果子类中也有和父类相对应的方法和属性的时候,调用时优先使用子类中的方法和属性:
m.run()
m.eat()
m.sleep()
Man.run(m)
Man.eat()
Man.sleep()
返回结果:
跑的很快
吃你的吧
快点做梦
跑的很快
吃你的吧
快点做梦
注意: 如果子类中没有属性和初始化属性的时候,直接使用子类是没办法使用父类中的初始化方法的。
print(Man.age)
print(m.age)
返回结果:
AttributeError: type object 'Man' has no attribute 'age' AttributeError: 'Man' object has no attribute 'age'
解决方法1:
class Man(Person):
def __init__(self):
Person.__init__(self) # 使用父类调用父类中的初始化方法,但是后期维护父类名称不能不懂,而且菱形多继承时可能发生属性重复
self.sex = 'man'
解决方法2:
class Man(Person):
def __init__(self):
super().__init__()
self.sex = 'man'