名称 | 描述 |
---|---|
封装 | 根据职责将对象的属性和方法封装到一个抽象的类中 |
继承 | 实现代码的重用,相同的代码不需要重复的编写 |
多态 | 不同的子类对象调用相同的父类方法,产生不同的执行结果,增加代码的灵活度 |
一、单继承
格式:
class 类名(父类名):
pass
子类拥有父类所有的属性和方法
子类应该根据职责,封装子类特有的属性和方法
1.1 继承的传递性
- 子类拥有父类以及父类的父类封装的所有属性和方法
C类从B类继承,B类又从A类继承,那么C类也从A类继承即C类具有B类和A类的所有属性和方法
1.2 专业术语
- Dog类是Animal类的子类,Animal类是Dog类的父类,Dog类从Animal类继承
- Dog类是Animal类的派生类,Animal类是Dog类的基类,Dog类从Animal类派生
eg:
class Animal:
@classmethod
def eat(cls):
print("吃")
@classmethod
def drink(cls):
print("喝")
@classmethod
def run(cls):
print("跑")
@classmethod
def sleep(cls):
print("睡")
class Dog(Animal):
@classmethod
def bark(cls):
print("汪汪汪......")
if __name__ == '__main__':
dog = Dog()
dog.eat()
dog.bark()
1.3 方法的重写 Override
方法的重写的类型 | 描述 |
---|---|
覆盖 | 直接覆盖父类的方法 |
扩展 | 对父类的方法进行扩展 |
eg:
- 覆盖
直接在子类中定义一个与父类同名的方法并实现
子类调用该方法时,会直接调用子类重写的方法,不会调用父类封装的方法
class Animal:
@classmethod
def eat(cls):
print("吃")
@classmethod
def drink(cls):
print("喝")
@classmethod
def run(cls):
print("跑")
@classmethod
def sleep(cls):
print("睡")
class Dog(Animal):
@classmethod
def bark(cls):
print("汪汪汪......")
@classmethod
def eat(cls):
print("我想吃肉...")
if __name__ == '__main__':
dog = Dog()
dog.eat()
结果:
- 扩展
适用于:重写父类方法时,调用父类封装的方法实现
使用
super().父类方法
来调用父类方法的执行
super()就是super类创建的对象使用
父类名.父类方法(self)
来调用父类方法的执行不推荐
一旦父类发生改变,方法调用位置的类名同样需要修改
不小心将父类名写成了当前子类名,会形成递归调用,出现死循环
class Animal:
@classmethod
def eat(cls):
print("吃")
@classmethod
def drink(cls):
print("喝")
@classmethod
def run(cls):
print("跑")
@classmethod
def sleep(cls):
print("睡")
class Dog(Animal):
@classmethod
def bark(cls):
print("汪汪汪......")
@classmethod
def eat(cls):
super().eat()
print("我想吃肉...")
if __name__ == '__main__':
dog = Dog()
dog.eat()
结果:
二、多继承
子类可以拥有多个父类,并且具有所有父类的所有属性和方法
注意:
- 父类之间存在同名的属性或方法,子类应尽量避免使用多继承
格式:
class 类名(父类名1, 父类名2, ..., 父类名n):
pass
eg:
class A:
@classmethod
def test(cls):
print("A")
pass
class B:
@classmethod
def demo(cls):
print("B")
class C(A, B):
pass
if __name__ == '__main__':
c = C()
c.test()
c.demo()
2.1 多继承的继承顺序
内置属性__mro__
查看方法的搜索顺序
提示:
- MRO(method resolution order)
主要用于判断子类使用多继承时,所有父类的属性、方法的调用路径
eg:
class A:
@classmethod
def test(cls):
print("A")
pass
@classmethod
def demo(cls):
print("A")
class B:
@classmethod
def demo(cls):
print("B")
@classmethod
def test(cls):
print("B")
pass
class C(A, B):
pass
if __name__ == '__main__':
c = C()
print(C.__mro__)
c.test()
c.demo()
结果:
可以看出:
- 在搜索方法时,是按照
__mro__
的输出结果从左到右的顺序查找的 - 在当前类中找到方法,就直接执行,不再搜索;如果没有找到,就查找下一个类中是否有对应的方法,如果找到方法,就直接执行,不再搜索;如果找到最后一个类,还没有找到方法,程序就报错
2.2 新式类和旧式(经典)类
object类是python为所有对象提供的基类,提供一些内置的属性和方法,可以通过dir()查看
print(dir(object))
类分类 | 描述 |
---|---|
新式类推荐
|
以object类为基类的类 |
经典类不推荐
|
不以object类为基类的类 |
- python3.x没有指定父类,默认object类为基类即python3.x定义的类都是新式类
- python2.x没有指定父类,则不会以object类为基类
- 为保证编写的代码能够同时在python3.x和python2.x运行,如果没有父类,统一继承自object类
class 类名(object):
pass
更新中......