类和对象 单继承和多继承
被继承的类可以称之为 ⽗类、基类、超类 。继承的类可以称之为 ⼦类、派⽣类 。派⽣和继承是⼀体两⾯,从⽗类向⼦类看就是派⽣,从⼦类向⽗类看就是继承。⼦类和⽗类的关系可以⽤“is a”类表示,即⼦类是⽗类的⼀种,是⼀个更具体、更加强⼤的⽗类。python⽀持单继承和多继承。
继承的优点:
可以简化代码,减少冗余度
提⾼了代码的可维护性
提⾼了代码的安全性
1.1 单继承
所谓的单继承就是⼀个⼦类只有⼀个⽗类。⼦类会继承⽗类所有的属性和⽅法。私有成员在⼦类中⽆法直接使⽤
⼦类对象⽆法直接使⽤继承⾃⽗类的私有成员⼦类⽅法和⽗类⽅法重名,通过⼦类对象调⽤的是⼦类⽅法
注意:object是Python中所有类的⽗类【⼀般情况下,如果⼀个类没有指明的⽗类,默认它的⽗类为object】
"""
class Animal:
def __init__(self,name):
self.name = name
self.__a = 10 # 父类的私有属性
def __sing(self): #父类的私有成员方法
print("唱歌")
def eat(self):
print("吃饭饭")
# class Cat(Animal):
# pass
# 子类继承了父类的所有属性和方法
# cat = Cat('加菲')
# print(cat.name)
# cat.eat()
# 改写方法,增加属性和方法
# class Cat(Animal):
# def __init__(self,name,age):
# self.name = name
# self.age = age
# # 可以覆盖继承自父类的同名方法
# def eat(self,something):
# super().eat() # super() 可以调用继承自父类的方法,不被子类同名方法所覆盖
# print(f"老猫吃了一只{something}") #字符串格式化的一种方法
#
# def walk(self): #在子类中动态增加一个walk方法
# print("猫步")
# cat = Cat('加菲猫',5)
# # 子类对象优先调用子类的同名方法(如果父类子类的某种方法同名,那么优先调用子类方法)
# cat.eat("老鼠")
# cat.walk()
# 构造方法的改写
# class Cat(Animal):
# def __init__(self,name,age):
# # 调用父类的构造方法初始化继承自父类的属性(以下是super的三种书写方法,建议使用第一种)
# # 1 使用super()调用继承自父类的方法
# # super().__init__(name)
# # 2. super(当前类名,self).__init__(参数)
# # super(Cat,self).__init__(name)
# # 3 父类类名.__init__(self,name)
# Animal.__init__(self,name)
# self.age = age
#
# cat = Cat('tom',3)
# 继承自父类的私有成员方法,在子类中不能直接使用
class Cat(Animal):
def test(self):
# 继承自父类的私有成员方法,在类内也不能直接访问
self.__sing()
cat = Cat('tom')
# 继承自父类的私有成员方法,不能在类外通过对象直接访问
# print(cat.__a)
# cat.__sing()
print(cat.__dict__) #查看实例有哪些属性
cat.test()
1.2 多继承(理解、了解)
⼀个⼦类可以有多个⽗类。
如果不同的⽗类中存在同名的⽅法,⼦类对象在调⽤⽅法时,会调⽤哪个⽗类的⽅
法?
Python中的MRO
Python中针对类提供了⼀个内置属性 mro 可以⽤来查看⽅法的搜索顺
序。
MRO 是 method resolution order 的简称,主要⽤于在多继承时判断⽅法属性
的调⽤顺序。
输出:
在调⽤⽅法时,按照 mro 的输出结果从左⾄右的顺序查找。
如果再当前类中找到⽅法,就直接执⾏,不再向下搜索。
如果没有找到,就顺序查找下⼀个类中是否有对应的⽅法,如果找到,就直接
执⾏,不再继续向下搜索。
如果找到了最后⼀个类,依然没有找到⽅法,程序就会报错。
class Base:
def __init__(self,a):
self.a = a
def hello(self):
print("Base")
class BaseA(Base):
def __init__(self,a,b):
Base.__init__(self,a)
self.b = b
def world(self):
self.hello()
class BaseB(Base):
def __init__(self,a,c):
super().__init__(a)
self.c = c
def example(self):
print("example")
class C(BaseA,BaseB):
pass
# 多继承下,子类只继承最左边类的属性
c = C(10,20)
print(c.__dict__)
# 方法的查找从左向右 按mro()方法提供的继承顺序进行调用
# c.hello()
# c.world()
# c.example()
# [<class '__main__.C'>, <class '__main__.BaseA'>, <class '__main__.BaseB'>, <class '__main__.Base'>, <class 'object'>]
print(C.mro())
万水千山总是情,点个关注(赞,收藏)行不行。
上一篇: Python高级——多继承问题(super与mro)
下一篇: Python高级之多继承与mro顺序