继承
先看个简单的例子了解一下继承。
class Animal: # 父类 def __init__(self, name, age, department): self.name = name self.age = age self.department = department def running(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 # 派生属性 class Mouse(Animal): def __init__(self, name, age, department, tail): super().__init__(name, age, department) # super方法只在python3中有 相当于Animal.__init__(self, name, age, department) self.tail = tail class Human(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()) # [<class ‘__main__.Human‘>, <class ‘__main__.Animal‘>, <class ‘object‘>]查看继承顺序 print(Human.__bases__) # <class ‘__main__.Animal‘>查看继承的所有父类
通过上面的例子总结一下继承的特性:
""" 继承:子类是父类的关系 作用:可以减少代码的重复 通过 类名(父类名) 来进行继承, 一个类可以单继承也可以多继承 一个类可以被单个类继承,也可以被多个类继承 父类中没有而子类中有的属性为 派生属性 父类中没有而子类中有的方法为 派生方法 单继承: 对象调用时,先在子类里找,子类里有一定用子类里的,没有再去父类里面找 多继承: 在新式类中(python3中都是新式类),对象调用查找是按广度查找 新式类,默认继承object 在经典类中,对象调用查找是深度查找 经典类,python2.7创建的默认类,继承object后变为新式类 """
研究一下继承的查找顺序:这里以python3为例
class D: def func(self): print(‘d‘) class C(D): def func(self): print(‘c‘) class B(D): def func(self): print(‘b‘) class A(B, C): def func(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方法的本质:
class A(object): def func(self): print(‘A‘) class B(A): def func(self): super().func() print(‘B‘) class C(A): def func(self): super().func() print(‘C‘) class D(B, C): def func(self): super().func() print(‘D‘) b = D() b.func() # 打印顺序为 A C B D # super的本质 :不是单纯找父类 而是根据调用者的节点位置的广度优先顺序来的
封装
封装 用于对代码的保护,使类中的隐藏属性和方法只有通过提供的公共访问方式来使用,而不能直接查。
下面写个例子具体看下:
class Person: __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‘) # 登陆成功
那子类能否继承父类的私有属性呢?
class Foo: __key = 123 class Son(Foo): print(Foo.__key) # 报错 子类不能继承父类的私用属性
多态
""" 多态:指一类事物有多种形态,python天生支持多态。 python中推崇鸭子类型,即看起来用起来都很像,但却没有任何约束关系,是一种自我约束行为。比如list和tuple 优点:松耦合,相似类之间不会有任何影响 缺点:自我约束,随意性太强 """
例子
class Holy: def cure(self, HP): HP += 100 return ‘血量为%s‘% HP class Discipline: def cure(self, HP): HP += 100 return ‘血量为%s‘% HP def cure(obj, HP): # 在强数据类型语言中,obj必须要指定数据类型,在Python中就可以是多种形态的 return obj.cure(HP) # 这里的Discipline类和Holy类就很相似,就可以当同一个事物去使用 holy = Holy() discipline = Discipline() print(cure(holy, 20)) print(cure(discipline, 10))