继承
⾯向对象编程(OOP) 语⾔的⼀个主要功能就是“继承”,所谓继承就是使现有的类⽆需编码便可以拥有原有类的⽅法和属性。
被继承的类可以称之为⽗类、基类、超类。继承的类可以称之为⼦类、派⽣类。派⽣和继承是⼀体两⾯,从⽗类向⼦类看就是派⽣,从⼦类向⽗类看就是继承。⼦类
和⽗类的关系可以⽤“is a”类表示,即⼦类是⽗类的⼀种,是⼀个更具体、更加强⼤的⽗类。python⽀持单继承和多继承。
继承的优点:
- 简化代码,减少冗余度
- 提⾼了代码的可维护性 (改父类,影响子类)
- 提⾼了代码的安全性
不足:当继承层级多的时候效率低
单继承
所谓的单继承就是⼀个⼦类只有⼀个⽗类。⼦类会继承⽗类所有的属性和⽅法。java,c#是单继承语言,python支持单继承和多继承。
- 私有成员在子类中无法直接使用
- 子类对象无法直接使用继承自父类的私有成员
- 子类方法与父类方法重名,则调用的是子类方法
继承的过程:获取父类的所有成员方法-改写继承自父类的方法-添加新的成员
# 定义父类
class Animal:
def __init__(self,name,age):
self.name = name
self.__age = age
def sleep(self):
print("睡觉觉")
def walk(self):
print("walk")
# 继承父类
class Dog(Animal):
pass
# a = Dog("小三",18) # 要按父类构造方法定义
class Dog(Animal):
def __init__(self,name,age,meng):#通过构造方法定义子类属性,则每一个属性都要重新定义,如果是来自父类的属性,可以用下列方法继承定义
super().__init__(name,age) # 通过父类定义子类属性
self.meng = meng # 通过一般构造方法增加新的属性
# 改写方法
class Dog(Animal):
def __init__(self,name,age,meng):#meng是新成员属性
super().__init__(name,age) # 实参不要加selt
self.meng = meng
def sleep(self):# 改写方法之完全重写父类方法
print("不睡")
def walk(self):# 改写方法之改进父类方法
super().walk()
print("我高兴")
def run(self): #增加方法
print("跑快点")
# 继承属性和增加属性的方法
# 第一种(上例所示)
# super().__init__(实参列表)#实参不要带self
class Dog(Animal):
def __init__(self,name,age,meng):
super().__init__(name,age)
self.meng=meng
# 第二种
# super(当前类名,self).__init__(实参列表) #实参不要带self
class Dog(Animal):
def __init__(self,name,age,meng):
super(Dog,self).__init__(name,age)
self.meng=meng
# 第三种(不建议)
# ⽗类名.__init__(self,其它参数)
class Dog(Animal):
def __init__(self,name,age,meng):
Animal.__init__(self,name,age)
self.meng=meng
子类继承父类后,如果子类的构造函数修改了属性,则会覆盖父类的同名或其他属性
多继承
C++是多继承,Python支持多继承
class A:
def __init__(self, name, age):
self.name = name
self.age = age
class B:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def age(self):
print(self.age)
class C(B, A):
pass
# 子类的属性如果不改写,则只继承第一个父类的属性
a = C("张三",18)
# 要查询继承顺序,则可使用mro()方法
print(C.mro())
#[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
# 该列表就是继承的顺序
# 如果A,B又有父类,C的属性继承就会比较复杂 ,就是典型的菱形继承,可查看mro()列表确定继承顺序
- 多重继承例子
class G:
def text(self):
print('g')
class E(G):
def text(self):
print('e')
class B(E):
def text(self):
print('b')
class F(G):
def text(self):
print('F')
class C(F):
def text(self):
print('D')
class D(G):
def text(self):
print('d')
class A(B,C,D):
def text(self):
print('a')
obj=A()
obj.text()
# 每个类都有text()方法,obj.text()执行就是按照mro()方法的列表顺序进行:ABECFDG,先找A本身的方法,然后先找B支,从B往上找到E,但G作为共用父类不找,返回再找C支(C、F),返回再找D支,最后找G.
# 顺序:ABECFDG