python学习之继承
继承
什么时候用继承(__dict__)
1.当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好
如:描述一个机器人类,机器人这个大类是由很多不相关的小类组成,如机器胳膊类,腿类,身体类
2.当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好
如 猫可以:喵喵叫、吃、喝、拉、撒、
狗可以:汪汪叫、吃、喝、拉、撒、
继承同时具有两种含义
含义一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)
含义二:声明某个子类兼容于某基类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法
实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合
继承的第二种含义非常重要。叫“接口继承”
接口继承实质上实要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,
可一视同仁的处理实现了特定接口的所有对象“---这在程序设计上,叫做归一化。
归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合
1.就好象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕
(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:
细致到什么程度,视需求而定)。
2.再比如:我们有一个汽车接口,里面定义了汽车所有的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,
他们都实现了汽车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是奥迪,
还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样
from abc import ABCMeta,abstractmethod
class Pet(object,metaclass=ABCMeta):
'''宠物'''
def __init__(self,nickname):
self._nickname=nickname
@abstractmethod
def make_voice(self):
'''发出声音'''
pass
class Dog(Pet):
'''狗'''
def make_voice(self):
print("%s:汪汪汪..."%self._nickname)
class Cat(Pet):
'''猫'''
def make_voice(self):
print("%s:喵喵喵"%self._nickname)
def main():
pets=[Dog('旺财'),Cat('凯蒂'),Dog('大黄')]
for pet in pets:
pet.make_voice()
if __name__=='__main__':
main()
MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类
子类调用父类的方法
class Vehicle:
Country='China'
def __init__(self,name,speed,load,power):
self.name=name
self.speed=speed
self.load=load
self.power=power
def run(self):
print('开动啦')
print('开动啦')
class Subway(Vehicle):
def __init__(self,name,speed,load,power,line):
Vehicle.__init__(self,name,speed,load,power)
self.line=line
def show_info(self):
print(self.name,self.speed,self.load,self.power,self.line)
def run(self):
Vehicle.run(self)
print('%s %s 线,开动啦' %(self.name,self.line))
line13=Subway('北京地铁','10km/s',1000000000,'电',13)
line13.show_info()
line13.run()
super()方法
class Vehicle1:
Country='China'
def __init__(self,name,speed,load,power):
self.name=name
self.speed=speed
self.load=load
self.power=power
def run(self):
print('开动啦')
print('开动啦')
class Subway(Vehicle1):
def __init__(self,name,speed,load,power,line):
# Vehicle.__init__(self,name,speed,load,power)
# super().__init__(name,speed,load,power) #super(__class__,self).__init__(name,speed,load,power)
super(Subway,self).__init__(name,speed,load,power)
self.line=line
def show_info(self):
print(self.name,self.speed,self.load,self.power,self.line)
def run(self):
# Vehicle.run(self)
super().run()
print('%s %s 线,开动啦' %(self.name,self.line))
line13=Subway('北京地铁','10km/s',1000000000,'电',13)
line13.show_info()
line13.run()
print(line13.__class__)