继承
先看个简单的例子了解一下继承。
class Animal: #父类
def __init__(self, name, age, department):
self.name=name
self.age=age
self.department=departmentdefrunning(self):print(‘%s可以奔跑!‘%self.name)class Cat(Animal): #括号里放要继承的父类
def __init__(self, name, age, department, tail):
Animal.__init__(self, name, age, department) #即想使用父类的属性又有自己独有的属性,就在内部调用父类的__init__
self.tail = tail #派生属性
classMouse(Animal):def __init__(self, name, age, department, tail):
super().__init__(name, age, department)#super方法只在python3中有 相当于Animal.__init__(self, name, age, department)
self.tail =tailclassHuman(Animal):def __init__(self, name, age, department):
Animal.__init__(self, name, age, department)def create(self): #派生方法
print(‘%s可以创造!‘%self.name)
cat= Cat(‘Tom‘, 10, ‘猫科‘, ‘蓝色尾巴‘)
mouse= Mouse(‘Jerry‘, 7, ‘鼠科‘, ‘灰色尾巴‘)
human= Human(‘zzy‘, 24, ‘人科‘)print(cat.name) #Tom
print(mouse.tail) #灰色尾巴
cat.running() #Tom可以奔跑!
human.create() #zzy可以创造!
print(Human.mro()) #[, , ]查看继承顺序
print(Human.__bases__) #查看继承的所有父类
继承
通过上面的例子总结一下继承的特性:
"""继承:子类是父类的关系 作用:可以减少代码的重复
通过 类名(父类名) 来进行继承,
一个类可以单继承也可以多继承
一个类可以被单个类继承,也可以被多个类继承
父类中没有而子类中有的属性为 派生属性
父类中没有而子类中有的方法为 派生方法
单继承:
对象调用时,先在子类里找,子类里有一定用子类里的,没有再去父类里面找
多继承:
在新式类中(python3中都是新式类),对象调用查找是按广度查找
新式类,默认继承object
在经典类中,对象调用查找是深度查找
经典类,python2.7创建的默认类,继承object后变为新式类"""
研究一下继承的查找顺序:这里以python3为例
classD:deffunc(self):print(‘d‘)classC(D):deffunc(self):print(‘c‘)classB(D):deffunc(self):print(‘b‘)classA(B, C):deffunc(self):print(‘a‘)
a=A()
a.func()#a A类里有就找A类
#注释掉A类里的func
a.func() #b A类里没有,先从括号中最左边的B类里找
#注释掉B类里的func
a.func() #c B类里没有,判断通过C类也能找到B的父类D,会从C类先找
#注释掉C类里的func
a.func() #d C类里没有,就找父类D
上面的继承顺序可以看出:
"""广度查找:原则就是在没找到时,按继承层级找完每一个父类
深度查找:原则是一条继承线路找到底才会找另外的线路"""
再看下super方法的本质:
classA(object):deffunc(self):print(‘A‘)classB(A):deffunc(self):
super().func()print(‘B‘)classC(A):deffunc(self):
super().func()print(‘C‘)classD(B, C):deffunc(self):
super().func()print(‘D‘)
b=D()
b.func()#打印顺序为 A C B D#super的本质 :不是单纯找父类 而是根据调用者的节点位置的广度优先顺序来的
封装
封装 用于对代码的保护,使类中的隐藏属性和方法只有通过提供的公共访问方式来使用,而不能直接查。
下面写个例子具体看下:
classPerson:__keys = ‘量子编码规则‘ #私有静态属性
def __init__(self, name, password):
self.name=name
self.__password = password #__属性 定义私有属性
def __get_password(self): #__方法 定义私有方法
return self.__password #只能在内部访问
def login(self, name, passwd): #提供公共访问方法
if name == self.name and passwd == self.__get_password():print(‘登陆成功‘)
person= Person(‘zzy‘, ‘zzy123‘)#print(person.__password) # 报错 显示Person类找不到__password#print(person._Person__password) # zzy123 在外部通过 _类名__属性名 也能查看私用属性,但是不能这样用!
person.login(‘zzy‘, ‘zzy123‘) #登陆成功
那子类能否继承父类的私有属性呢?
classFoo:__key = 123
classSon(Foo):print(Foo.__key) #报错 子类不能继承父类的私用属性
多态
"""多态:指一类事物有多种形态,python天生支持多态。
python中推崇鸭子类型,即看起来用起来都很像,但却没有任何约束关系,是一种自我约束行为。比如list和tuple
优点:松耦合,相似类之间不会有任何影响
缺点:自我约束,随意性太强"""
例子
classHoly:defcure(self, HP):
HP+= 100
return ‘血量为%s‘%HPclassDiscipline:defcure(self, HP):
HP+= 100
return ‘血量为%s‘%HPdef cure(obj, HP): #在强数据类型语言中,obj必须要指定数据类型,在Python中就可以是多种形态的
returnobj.cure(HP)#这里的Discipline类和Holy类就很相似,就可以当同一个事物去使用
holy =Holy()
discipline=Discipline()print(cure(holy, 20))print(cure(discipline, 10))