上一篇:继承的使用 | 手把手教你入门Python之六十三
下一篇:Python2和Python3的区别 | 手把手教你入门Python之六十五
本文来自于千锋教育在阿里云开发者社区学习中心上线课程《Python入门2020最新大课》,主讲人姜伟。
继承的注意事项
在Python中,继承可以分为单继承、多继承和多层继承。
单继承:⼦类只继承⼀个⽗类
继承概念:⼦类⽤于⽗类的所有的⽅法和属性。
不使用继承:
使用继承:
继承语法:
class 类名(⽗类名):
pass
- ⼦类继承⾃⽗类,可以享受⽗类中已经封装好的⽅法,不需要再次定义
- ⼦类中应该根据职责,封装⼦类特有的属性和⽅法。
继承的传递性
Dog类继承⾃Animal,XiaoTianQuan⼜继承⾃Dog类,那么XiaoTianQuan类就具有了Animal类⾥的所有属性和⽅法。
⼦类拥有⽗类以及⽗类的⽗类中封装的所有属性和⽅法。
思考:
XiaoTianQuan能否调⽤Animal的run()⽅法? XiaoTianQUan能够调⽤Cat⾥的⽅法?
多继承
⼦类可以拥有多个⽗类,并且具有所有⽗类的属性和⽅法。
语法格式:
class ⼦类名(⽗类名1,⽗类名2...)
pass
多继承的使⽤注意事项
思考:
如果不同的⽗类中存在同名的⽅法,⼦类对象在调⽤⽅法时,会调⽤哪个⽗类的⽅法? 说明:开发中,应该尽量避免这种容易产⽣混淆的情况。如果多个⽗类之间存在同名的属性后者⽅法,应该尽量避免使⽤多继承。
Python中的MRO
- Python中针对类提供了⼀个内置属性
__mro__
可以⽤来查看⽅法的搜索顺序。 - MRO 是
method resolution order
的简称,主要⽤于在多继承时判断⽅法属性的调⽤顺序。
print(C.__mro__)
输出结果:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
- 在调⽤⽅法时,按照
__mro__
的输出结果从左⾄右的顺序查找。 - 如果再当前类中找到⽅法,就直接执⾏,不再向下搜索。
- 如果没有找到,就顺序查找下⼀个类中是否有对应的⽅法,如果找到,就直接执⾏,不再继续向下搜索。
- 如果找到了最后⼀个类,依然没有找到⽅法,程序就会报错。
class A(object):
def demo_a(self):
print('我是A类里的方法demo_a')
def foo(self):
print('我是A类里的foo方法')
class B(object):
def demo_b(self):
print('我是B类里的方法demo_b')
def foo(self):
print('我是B类里的foo方法')
# python里允许多继承
class C(A, B): # 如果不写父类,python3以后,默认继承自object
pass
c = C()
c.demo_a() # 我是A类里的方法demo_a
c.demo_b() # 我是B类里的方法demo_b
# 如果两个不同的父类有同名方法,有一个类属性可以查看方法的调用顺序
c.foo() # 我是A类里的foo方法
print(C.__mro__) # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
私有属性继承特点
class Animal(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.__money = 1000
def eat(self):
print(self.name + '正在吃东西')
def __test(self):
print('我是Animal类里的test方法')
class Person(Animal):
def __demo(self):
print('我是Person里的私有方法')
p = Person('张三', 18)
print(p.name) # 张三
p.eat() # 张三正在吃东西
# p.__test() # 出错
p._Person__demo() # 自己类里定义的私有方法 对象名._类名__私有方法()
p._Animal__test() # 我是Animal类里的test方法 可以通过 对象名._父类名__私有方法()调用
# 私有属性和方法,子类不会继承
# p._Person__test() # 出错 父类的私有方法,子类没有继承
# print(p._Person__money) # 出错
print(p._Animal__money) # 1000
新式类和旧式(经典)类
# -*- coding:utf8-*-
# 手动指定Student类继承自object
class Student(object):
pass
# 没有指定Dog的父类,python3里默认继承自object
class Dog:
pass
object
是Python中所有对象的基类,提供了⼀些内置的属性和⽅法,可以时候⽤ dir
函数查看。
- 新式类:以
object
为基类的类,推荐使⽤ - 经典类:不以
object
为基类的类,不推荐使⽤ - 在 Python3.x 以后定义类时,如果没有指定⽗类,这个类会默认继承⾃
object
,所以,python3.x版本定义的类都是新式类。 - 在Python2.x中定义类时,如果没有指定⽗类,则不会继承⾃
object
,这个类是一个经典类。
为了保证代码在Python2.x和Python3.x中都能够运⾏,在定义类时,如果⼀个类没有⽗类,建议统⼀继承⾃object
class 类名(object):
pass