组合
-
什么是组合:一个对象的属性来自于另一个类的对象,称之为组合,那这个对象就获得了另一个对象的属性和功能
-
使用组合的目的
解决代码冗余的问题
-
如何使用组合
class Phone: def __init__(self,phonenumber,operator,address): self.phonenumber = phonenumber self.operator = operator self.address = address def call(self): print("%s 正在拨号" % self.phonenumber) class Person: def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age class Student(Person): def __init__(self,name,sex,age,number): super().__init__(name, sex, age) self.number = number def show_info(self): print(self.__dict__) def select_course(self): print("%s 正在选课...." % self.name) class Teacher(Person): def __init__(self,name,sex,age,salary,level): super().__init__(name,sex,age) self.salary = salary self.level = level def set_score(self): print("%s 正在为学生打分..." % self.name) stu = Student("乔峰","男",38,"007") # 学生买了一台手机 所以增加一个手机属性 p1 = Phone("1999999999","中国小米移动","上海浦东") stu.phone = p1 # 组合代码 # 学生要打电话 stu.phone.call()
-
组合与继承的区别:
-
继承是一种方法,是类与类之间的关系,是同类只间的的传递
-
组合是对象之间的关系
-
封装
-
封装:在程序中,封装指的是将内容隐藏起来,在面向对象种隐藏的是属性和方法
注意:封装不是单纯的隐藏,只是隐藏内部细节,对外提供使用接口
-
封装的目的:
-
提高安全性:
-
对于封装属性而言,是通过给访问和修改增加额外的验证来实现
-
对于封装方法而言,提高安全性,和隔离复杂度(将复杂的内容隔离到内部,外部只留下简单的接口,对于使用者,难度降低)
-
-
封装是为了明确区分内部和外部
-
对于封装方法而言,可以隔离复杂度
-
-
如何封装:
-
属性的封装:
在属性或者方法名称前添加两个下划线"__" ,就可以将其设置成私有的
补充:在python中权限只有两种,公开(谁都能访问)和私有的(只有自己能访问的)
# 封装属性 class Student: def __init__(self, name, age, sex, id_card): self.name = name self.age = age self.sex = sex self.__id_card = id_card # 在属性前加__,对其封装 def say_hi(self): print('hello i am %s age is :%s sex is %s' % (self.name, self.age, self.sex)) def test(self): print(self.__id_card) # 訪問封裝屬性 def get_id_card(self): return self.__id_card # 加密访问 def get_id(self, pwd): if pwd == 123: return self.__id_card else: return '密码错误' # 修改封裝屬性 def set_id(self, pwd, new_id): if pwd == 1234: self.__id_card = new_id stu = Student('jason', 23, 'male', '1234567') print(stu.get_id(123)) # 修改封装前 stu.set_id(1234, 'xxxxxx') # 执行修改 print(stu.get_id_card()) # 执行修改后结果 # 运行结果 1234567 xxxxxx # 对方法进行封装 class Atm: def __insert_card(self): print('插入银行卡') def __input_pwd(self): print('输入密码') def __selectmoney(self): print('选择金额') def withdraw(self): self.__insert_card() self.__input_pwd() self.__selectmoney() print('取款成功') atm = Atm() atm.withdraw()
-
-
封装的特点:
-
在类的内部可以访问得到,类的外部无法访问
-
-
封装的实现原理
本质上python并没有强行限制你的访问,而是通过方法的转换进行封装
-
通过__ dict__ 可以发现 私有的属性名称 前自动加上了__类名 python就是这样的转换方式实现的封装.
-
只有在类的内部的双下划线才会被自动转换,并且这个转换过程只执行一次,在类定义完成后,再添加的双下划线开头的名称是不会自动装换的.
-
父类中私有的方法,子类中无法使用
-
-
property装饰器
-
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
-
为什么要用property
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
-
什么时候用property
当一个属性不是固定需要计算得来时,调用时还是要以属性的调用方式,这个时候我们就要用property为其装饰.
- setter和deleter,修改和删除被property伪装的函数属性
class People: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height @property # 添加装饰器 def bmi(self): return self.weight / (self.height**2) p1 = People('Jason', 78, 1.83) print(p1.bmi) # 函数伪装后的属性的访问方法访问,不可赋值和删除 # 如果非要修改赋值,那么就要用到setter装饰器 # 如果非要删除,就要用到delter装饰 class Student: def __init__(self,name,sex,idCard): self.name = name self.sex = sex self.__idCard = idCard def get_idCard(self): return self.__idCard def set_idCard(self, new_id): self.__idCard = new_id @property # 需要掌握 def idCard(self): return self.__idCard @idCard.setter # 更改伪装属性 def idCard(self,new_id): self.__idCard = new_id @idCard.deleter # 删除伪装属性 def idCard(self): print("身份证属性被删除了.....") del self.__idCard stu = Student("尔康","男","323254554554") print(stu.get_idCard()) # 使用装饰器前 print(stu.name) # 普通属性的访问 print(stu.idCard) # 使用装饰器后 stu.idCard = "aaaaaaa" # 使用装饰器后的修改操作 print(stu.idCard)