今日所学:
什么是封装
对外部隐藏内部的属性,以及实现细节,给外部提供使用的接口。 注意:封装有隐藏的意思,但不是单纯的隐藏
为什么封装
1,提高安全性。2,隔离复杂度
学习封装的目的,就是为了能够限制外界对内部的数据的访问。python中属性的权限有两种:
1》公开的:没有 任何限制,谁都能访问
2》私有的:只有当前类本身可以用
# 案例:怎样进行封装 class Student: def __init__(self,name,age,gender,id_card): self.name = name self.age = age self.gender = gender self.__id_car = id_card def show_id_card(self): #进行封装,访问一个私有被封装的方法 # 可以在这里添加额外的任何逻辑代码,来限制外部的访问 print(self.__id_card) #完成封装 封装的方法 stu1 = Student("rose",20,",man","1111111111111111111") print(stu1.name) #结果为 rose # print(stu1.__id_card) #这样访问不了id_card ,报错 print(Student.__id_card) #这样可以访问,结果为rose,即只有当前类本身能够访问 stu1.show_id_card() #结果为 rose # ########## # 封装属性:提现了安全性 class Student: def __init__(self, name, age, gender, id_card): self.name = name self.age = age self.gender = gender self.__id_card = id_card # 称之为访问器,生成器,即定义一个方法来访问被封装的属性,这个方法叫访问器 def get_id_card(self): #进行封装,访问一个私有被封装的方法 # 可以在这里添加额外的任何逻辑代码,来限制外部的访问 print(self.__id_card) return self.__id_card #修改被封装的属性 称之为设置器 def set_id_card(self,new_id): #从外界传入一个新的值 #案例:身份证号码必须是字符串类型,长度必须是18位 if isinstance(new_id, str) and len(new_id) ==18: self.__id_card = new_id else: print("身份证号码错误,必须是字符串,且长度必须为18") self.__id_car = new_id stu1 = Student("rose", 20, ",man", "1111111111111111111") stu1.show_id_card() # stu1.set_id_card("22222222222222") # stu1.show_id_card() id = stu1.get_id_card() print(id) stu1.set_id_card(123) #结果为:身份证号码错误,必须是字符串,且长度必须为18 stu1.set_id_card("123456789987654321") print(stu1.get_id_card()) #结果为123456789987654321 # 总结:在set_id_card中可以增加限制,和满足你所需求的功能,对其封装的进行修改 # 同理。在get_id_card中也可以怎加限制,例如判断满足的条件,判断合法就访问,对其用户进行了限制 # 目的:是为了保证安全性。除了可以封装属性,还可以封装方法 # 封装方法:体现了隔离复杂度 class ATM: def withdraw(self): self.__user_auth() self.__input_money() self.__save_record() def __user_auth(self): print("请输入账号密码...") def __input_money(self): print('请输入取款金额,余额为10000元') def __save_record(self): print("记录流水") atm = ATM() atm.withdraw() # 总结:1,什么样的方法应该被封装起来: # 一个为内部提供支持方法,不应该让外界直接访问,就把它藏起来,如上例中的__user_auth #如何封装的:封装原理 # 就是把名字做了修改,通过修改名字的方法,即变形 # 如何变形,就是在名称带有双下划线开头的变量名字前加了_类名 如_Person_id_card # 注意:变形这个操作是在定义类的时候发生的,只发生一次, # 后续再添加的带有双下划线的任何属性,都将不会变形 #什么时候应该封装属性: # 如银行卡密码,这种属性就不能直接被外界使用,要封装起来 class Teacher: def __init__(self, name, age, salary): self.name = name self.age = age self.__salary = salary @property def get_salary(self): return self.__salary def set_salary(self, new_salary): self.__salary = new_salary t =Teacher("fee",23,16000) print(t.get_salary()) t.set_salary(20000) print(t.get_salary()) print(t.name) # 出现的问题:被封装的属性在访问时,需要调用方法,而普通属性直接点就ok # 这样一来对于使用者而言,必须要知道访问的属性,是私有还是公开, # 然后调用对象的方法比较麻烦的。此时,我们的目标是,让访问的私有属性 # 和访问普通属性的方式一致,这时候就需要property装饰器,就是将一个私有的伪装成共有的 class Teacher: def __init__(self, name, age, salary): self.name = name self.age = age self.__salary = salary @property #用于访问私有属性的值 相当于getter def salary(self): return self.__salary @salary.setter #用来设置私有属性的值,@上面那个被装饰的函数(注意) def salary(self, new_salary): self.__salary = new_salary @salary.deleter #用来删除私有属性的值 def salary(self, a): print(a) t = Teacher("WWW",22,11111) t.salary = 500 print(t.salary) print(t.__dict__) #通常使用 @property来访问私有的,希望将私有属性变为普通属性访问标准解释:多个不同类型对象,可以响应同一个方法,并且产生不同结果
1.增加了程序的灵活性
以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)
2.增加了程序额可扩展性
通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用
比如:老师.下课铃响了(),学生.下课铃响了(),老师执行的是下班操作,学生执行的是放学操作,虽然二者消息一样,但是执行的效果不同
import abcclass Animal(metaclass=abc.ABCMeta): #同一类事物:动物 @abc.abstractmethod def talk(self): pass
class People(Animal): #动物的形态之一:人 def talk(self): print('say hello')
class Dog(Animal): #动物的形态之二:狗 def talk(self): print('say wangwang')
class Pig(Animal): #动物的形态之三:猪 def talk(self): print('say aoao')
# 类中的内置函数:# 1__str__class Person: # 将对象转成字符串的时候执行 def __str__(self): print("str run") return "ffff"p = Person()# str(p) str run# 在默认的object 中,不要方法也可以实现,可以自己定义,去覆盖原来的定义,想要实现自己的功能# 再打印时,通过自定义的效果,返回值必须是字符串类型,该方法在object 中,子类可以覆盖该方法来进行自定义
转载于:https://www.cnblogs.com/Fzhiyuan/p/10897079.html
