封装方法: 给方法名字前面加上双下划线
封装方法的好处:.1.提高安全性2.隔离复杂度 (将复杂的内容隔离到内部 外部只留下简单的接口)


1 class ATM: 2 def __insert_card(self): 3 print("插入银行卡...") 4 5 def __input_pwd(self): 6 print("输入密码...") 7 def __select_money(self): 8 print("选择取款金额...") 9 def withdraw(self): 10 self.__insert_card() 11 self.__input_pwd() 12 self.__select_money() 13 print("取款成功!....") 14 15 atm = ATM() 16 17 atm.withdraw()
封装的实现原理:
通过__dict__ 可以发现
1.私有的属性和方法名称 前自动加上了_类名 python就是通过这样的转换方式来实现封装
2.只有在类的内部的双下划线才会被自动转换,并且这个转换过程只执行一次,在类定义完成后 后续添加的双下划线开头的名称是不会自动转换的
3.父类中私有的方法 子类中无法使用
property装饰器
当一些属性的值 不是固定的而是通过计算得来的时候 我们必须为这个属性增加方法才能完成计算
但是一旦使用方法后 该属性的访问就变成了方法的调用 很明显与其他的属性访问方式不同,这样给使用者造成迷惑 所以需要将这个方法伪装成普通属性 这就用到了Property
property可以将方法伪装成属性 利用这个特点 我们也可以将其使用到封装中 之前没有这个装饰器我们需要为私有的属性 提供两个方法 但是这样一来方位私有属性时的方式就发生了变化
这时候就可以使用property来进行伪装 使得访问私有属性与访问普通属性的方式一致
另外 property还提供了 setter(用于修改属性的值) 和 deleter(删除属性的值)


1 class Student: 2 def __init__(self,name,sex,idCard): 3 self.name = name 4 self.sex = sex 5 self.__idCard = idCard 6 7 def get_idCard(self): 8 return self.__idCard 9 10 def set_idCard(self,new_id): 11 self.__idCard = new_id 12 13 @property # 需要掌握 14 def idCard(self): 15 return self.__idCard 16 17 18 @idCard.setter #了解的 19 def idCard(self,new_id): 20 self.__idCard = new_id 21 22 @idCard.deleter # 了解的 23 def idCard(self): 24 print("身份证属性被删除了.....") 25 del self.__idCard 26 27 28 stu = Student("尔","男","323254554554") 29 print(stu.get_idCard()) # 使用装饰器前 30 print(stu.name) # 普通属性的访问 31 32 print(stu.idCard) # 使用装饰器后 33 stu.idCard = "aaaaaaa" # 使用装饰器后的修改操作 34 print(stu.idCard) 35 del stu.idCard 36 print(stu.__dict__) 37 print(Student.__dict__)
多态:
多态是多个类的对象拥有相同的方法,但是我们没有从严格要求说必须提供这些方法,子类完全可以不提供这些方法
如何实现多态?
让几个不同类拥有相同父类,这样一来他们就具备了相同的方法,每个子类要覆盖父类的方法,从而每个类的对象行为都不同


1 class Animal: 2 def eat(self): 3 print("动物在吃东西...") 4 def sleep(self): 5 print("动物在睡觉...") 6 def drink(self): 7 print("动物需要水.....") 8 9 10 class Person(Animal): 11 def eat(self): 12 print("人吃粮食...") 13 14 class Pig(Animal): 15 def eat(self): 16 print("猪吃饲料...") 17 18 class Dog(Animal): 19 def eat(self): 20 print("狗吃骨头...") 21 22 23 person = Person() 24 pig = Pig() 25 dog = Dog() 26 27 person.eat() 28 pig.eat() 29 dog.eat()
abstract class 是抽象类的缩写 抽象的意思是 不清晰 不具体 看不懂
使用ABC模块来限制子类 的步骤
1.为类中指定元类为abc.ABCMeta
2.在相应的方法上加上abc.abstractmethod装饰器


1 class Animal(metaclass=abc.ABCMeta): 2 3 @abc.abstractmethod 4 def eat(self): 5 pass 6 7 @abc.abstractmethod 8 def drink(self): 9 pass 10 11 12 class Cat(Animal): 13 def eat(self): 14 print("猫爱吃鱼肉...") 15 16 def drink(self): 17 print("用舌头舔..") 18 19 class Dog(Animal): 20 def eat(self): 21 print("狗爱吃骨头...") 22 def drink(self): 23 print("用舌头舔..") 24 25 class Pig(Animal): 26 def eat(self): 27 print("猪 爱吃草...") 28 29 def drink(self): 30 print("用嘴吸的..") 31 32 p = Pig() 33 # p.eat() 34 35 c = Cat() 36 # c.eat() 37 38 # 多态的好处 完全不需要考虑得到的对象时声明类型 只要知道了其基类中的内容就能使用 39 def feeding(animal): 40 animal.eat() 41 animal.drink() 42 43 feeding(c) 44 feeding(p) 45 # 多态中的基类 相当于(协议 标准 规范) 要求子类必须满足这些标准
鸭子类型:
只要你的行为一样 那就把你当成同一个类型来看待


1 class Duck: 2 3 def bark(self): 4 print("鸭子嘎嘎叫...") 5 6 def run(self): 7 print("摇摇晃晃走....") 8 9 class Chicken: 10 11 def bark(self): 12 print("鸡咯咯叫...") 13 14 def run(self): 15 print("摇摇晃晃走....") 16 17 def test(obj): 18 obj.bark() 19 obj.run() 20 duck = Duck() 21 c = Chicken() 22 23 test(duck) 24 test(c)