python面向对象——三大特性
1. 引言
Python是面向对象的语言,自然也支持面向对象的三大特性:封装、继承、多态。
因为Python2已经较为古老,所有除非是阐述区别,大部分情况下Python2的经典类在博文中我都会忽略。
2. 继承
继承是一种创新类的方式,在Python中,新建的类可以继承一个或多个父类,父类又可以称为基类或超类,新建的类称为派生类或子类。
Python中的类的继承可分为:单继承和多继承
优点:减少了代码的冗余
实现了代码的重用,子类可以继承父类,并且可以继承多个父类(多继承),子类可以使用父类所拥有的的属性和方法(除私有属性和方法)
2.1 代码实现——单继承和多继承
class ParentClass1:
pass
class ParentClass2:
pass
class SubClass1(ParentClass1):
pass
class SubClass2(ParentClass2):
pass
# 查看继承
print(SubClass1.__bases__) # __base__只能查看从左到右第一个子类,__bases__则是查看所有继承的父类
print(SubClass2.__bases__)
# 输出
(<class '__main__.ParentClass1'>,)
(<class '__main__.ParentClass2'>,)
经典类和新式类的区别:
- 只有在Python2中才有新式类和经典类,Python3中统一都是新式类
- 在Python2中,没有显示的继承object类的类,以及该类的子类都是经典类
- 在Python2中,显示的声明继承object的类,以及该类的子类都是新式类
- 在Python3中,默认继承object类,object类继承自type类(我们通过继承type类来创建元类),即Python3所有的类都是新式类
2.2 继承与抽象
抽象就是抽取类似的,或者比较像的部分。抽象最主要的作用是划分类别(隔离关注点,降低复杂度)
下图中,奥巴马和梅西被抽象成类;人、猪、狗被抽象成父类;
继承:是基于抽象的结果,通过编程实现,先经历抽象这个过程,才能过过继承的方式表达抽象结构
下图中,人、猪、狗都继承了动物父类,成为了动物父类的子类,然后将类实例化为具体的人物或形象。
2.3 继承与重用性
在开发的过程中,我们定义了一个A类,然后又想建立一个B类,但是B类的大部分内容与A类相同,我们就不用重写B类,只需要让B类继承A类,这就是类的继承的理念。
当B类继承A类后,B类就会或者A类中的属性,实现代码重用,这就是重用性。
下面我们通过一个动物的类实现来示范类的继承和重用性。
class Animal:
'''
创建了一个Animal类,作为父类,后续让Dog类和Person类继承
'''
def __init__(self, name, attacking, life_value):
self.name = name # 人和狗都具有名字属性
self.attacking = attacking # 人和狗都会攻击
self.life_value = life_value # 人和狗都具有生命值
def eat(self):
print('{}在吃饭'.format(self.name))
class Dog(Animal):
'''
Dog类,继承了Animal类,具有了Animal类中的所有属性
'''
def bite(self,people):
'''
派生:狗具有咬人技能
'''
people.life_value -= self.attacking
class Person(Animal):
'''
人类,继承Animal类,具有Animal类中的所有属性
'''
def attack(self, dog):
'''
人具有攻击技能
'''
dog.life_value -= self.attacking
egg = Person('奥巴马',10,1000)
ha = Dog('二傻',50,1000)
print(ha.life_value)
print(egg.attack(ha))
print(ha.life_value)
2.4 派生
子类也可以添加自己新的属性和定义旧的属性,这些都不会影响到父类,但是一定重新定义了自己的属性,且属性名和父类相同,那么调用该属性时,就会调用新的属性。
class Lol:
def __init__(self, hero_name, attacking, life_value):
self.hero_name = hero_name
self.attacking = attacking
self.life_value = life_value
def move_top(self):
print('{} 已到上路,请支援'.format(self.hero_name))
def move_mid(self):
print('{} 已到上中,请支援'.format(self.hero_name))
def move_end(self):
print('{} 已到下路,请支援'.format(self