Python——面向对象三大特性之继承
参考博文:https://www.cnblogs.com/songzhixue/p/10058957.html
一、继承
1、单继承与多继承
类的继承跟现实生活中的父子,爷爷孙子的关系类似。父类又称为基类。
python中类的继承分为:单继承和多继承
class Grandfather:
pass
class Father(Grandfather):#单继承
pass
class Son(Father,Grandfather):#多继承(Father要放在Grandfather的前面)
pass
2、子类继承了父类的什么属性?
子类继承了父类的所有属性,子类的属性如果与父类重名了,则优先取子类的属性,并不会覆盖父类的属性
3、什么时候用继承?
当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好
例如:
人:吃喝拉撒,玩电脑
狗:吃喝拉撒,汪汪汪
class 基础:
def 吃():
def 喝():
def 拉():
def 撒():
class 人(基础):
def 玩电脑():
class 狗(基础):
def 汪汪汪():
从原有的东西衍生出新的,称为派生
4、继承的两种含义
含义一:继承基类的方法,并且做出自己的改变或者拓展(代码重用,但是子类与父类的耦合度高,意义不大,甚至常常有害!)
含义二:声明某个子类兼容于某基类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法(更多的是使用这种含义。大白话讲,就是父类规定了子类要写什么方法,但是父类可以不用写,你子类只要继承了我父类,就必须按照我规定的方法来写。)
例如:现在定义一个基类,里面规定了读和写方法,要求所有继承该基类的子类都必须实现读与写方法,如下图
class All_file:
def read(self):
pass
def write(self):
pass
class Disk(All_file):
def read(self):
print("disk read")
def write(self):
print("disk write")
但是有个问题,如果我子类删除其中一个方法,不完全按照你父类规定的来,你父类又能怎样?子类根本没有受到限制。
所以为了实现这个功能,需要导入abc模块(不要怀疑,就叫abc)。具体实现如下:
import abc
class All_file(metaclass=abc.ABCMeta):
@abc.abstractmethod
def read(self):
pass
@abc.abstractmethod
def write(self):
pass
class Disk(All_file):
def read(self):
print("disk read")
def write(self):
print("disk write")
在基类后面需要添加 (metaclass=abc.ABCMeta),之后在每一个方法上面添加装饰器 @abc.abstractmethod,就能限制子类。具体效果是:如果子类没有完全按照基类的规定来,并不会报错,但在实例化子类的时候,会报错
这种也叫归一化设计,也就是一切皆文件的思想
5、继承顺序
如果有多个继承,想要查看继承顺序,可以通过__mro__,来查看
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B):
pass
class E(C):
pass
class F(D,E):
pass
print(F.__mro__)
最后发现会有个 <class ‘object’> ,A没有继承,默认 object 。
6、子类中调用父类的方法
通过 super 方法,来调用父类中的方法
class A:
def __init__(self,name,age):
self.name = name
self.age = age
def rush(self):
print("开冲")
class B(A):
def __init__(self,name,age,heigh):
super().__init__(name,age)
self.heigh = heigh
def rush(self):
print("不开冲")
super().rush()
b1 = B("张三",18,"175cm")
b1.rush()
以上代码能看到,子类想要调用父类的方法,通过 super.父类方法 ,就能完成。在初始化函数中,super().__init __后面的括号不需要写 self 。
最后,效果为: