对象初阶_继承
Posted zxmbky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对象初阶_继承相关的知识,希望对你有一定的参考价值。
继承
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类
python中类的继承分为:单继承和多继承
class ParentClass1: #定义父类 pass class ParentClass2: #定义父类 pass class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass pass class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类 pass
查看继承
>>> SubClass1.__bases__ #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类 (<class ‘__main__.ParentClass1‘>,) >>> SubClass2.__bases__ (<class ‘__main__.ParentClass1‘>, <class ‘__main__.ParentClass2‘>)
提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。
>>> ParentClass1.__bases__ (<class ‘object‘>,) >>> ParentClass2.__bases__ (<class ‘object‘>,)
继承与重用性
在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时
我们不可能从头开始写一个类B,这就用到了类的继承的概念。
通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用
派生
类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。
在子类中,新建的重名的函数属性,在编辑函数内功能的时候,有可能需要重用父类中重名的那个函数功能,应该是用调用普通函数的方式,即:类名.func(),此时就与调用普通函数无异了,因此即便是self参数也要为其传值.
在python3中,子类执行父类的方法也可以直接用super方法.
class A: def hahaha(self): print(‘A‘) class B(A): def hahaha(self): super().hahaha() #super(B,self).hahaha() #A.hahaha(self) print(‘B‘) a = A() b = B() b.hahaha() super(B,b).hahaha() 帮你了解super
class Animal: ‘‘‘ 人和狗都是动物,所以创造一个Animal基类 ‘‘‘ def __init__(self, name, aggressivity, life_value): self.name = name # 人和狗都有自己的昵称; self.aggressivity = aggressivity # 人和狗都有自己的攻击力; self.life_value = life_value # 人和狗都有自己的生命值; def eat(self): print(‘%s is eating‘%self.name) class Dog(Animal): ‘‘‘ 狗类,继承Animal类 ‘‘‘ def __init__(self,name,breed,aggressivity,life_value): super().__init__(name, aggressivity, life_value) #执行父类Animal的init方法 self.breed = breed #派生出了新的属性 def bite(self, people): ‘‘‘ 派生出了新的技能:狗有咬人的技能 :param people: ‘‘‘ people.life_value -= self.aggressivity def eat(self): # Animal.eat(self) #super().eat() print(‘from Dog‘) class Person(Animal): ‘‘‘ 人类,继承Animal ‘‘‘ def __init__(self,name,aggressivity, life_value,money): #Animal.__init__(self, name, aggressivity, life_value) #super(Person, self).__init__(name, aggressivity, life_value) super().__init__(name,aggressivity, life_value) #执行父类的init方法 self.money = money #派生出了新的属性 def attack(self, dog): ‘‘‘ 派生出了新的技能:人有攻击的技能 :param dog: ‘‘‘ dog.life_value -= self.aggressivity def eat(self): #super().eat() Animal.eat(self) print(‘from Person‘) egg = Person(‘egon‘,10,1000,600) ha2 = Dog(‘二愣子‘,‘哈士奇‘,10,1000) print(egg.name) print(ha2.name) egg.eat()
通过继承建立了派生类与基类之间的关系,它是一种‘是‘的关系,比如白马是马,人是动物。
当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师
继承顺序
1.python的类可以继承多个类,Java和c#则只能继承一个类
2.Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先,广度优先
当类是经典类时,多继承情况下,会按照深度优先方式查找(从左到右一直沿一条路径走到底再返回的方式遍历)
当类是新式类时,多继承情况下,会按照广度优先方式查找(从左到右以最短路径遍历每个父类)
3.经典类和新式类,从字面上可以看出一个老一个新,新的必然包含更多的功能,也是之后推荐的写法,基类或者父类继承了object类,那么该类便是新式类,否则便是经典类
4.python2中才分经典类和新式类,python3中统一都是新式类
python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如
>>> F.mro() #等同于F.__mro__ [<class ‘__main__.F‘>, <class ‘__main__.D‘>, <class ‘__main__.B‘>, <class ‘__main__.E‘>, <class ‘__main__.C‘>, <class ‘__main__.A‘>, <class ‘object‘>]
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类
以上是关于对象初阶_继承的主要内容,如果未能解决你的问题,请参考以下文章