面向对象之封装
一.面向对象精髓
将要处理的数据和处理数据的方法绑定在一起,得到一个对象。
二.组合
1.什么是组合?
组合是对象与对象之间的关系。
组合:指的是一个对象将另一个对象作为自己的属性。
2.为什么用组合?
为了减少代码冗余,还可以降低耦合度。
3.如何用组合?
当我们一个对象拥有某种属性时,而这个属性(对象)又拥有某些属性和方法,这时就需要用到组合这种方式。用法就是将将对象添加一个属性,这个属性它又是一个对象。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Person: def __init__(self,name,sex,age,phonenumber,operator,address): self.name = name self.sex = sex self.age = age self.phonenumber = phonenumber self.operator = operator self.address = address def call(self): print("%s 正在拨号" % self.phonenumber) class Student(Person): def __init__(self,name,sex,age,number,phonenumber,operator,address): super().__init__(name, sex, age,phonenumber,operator,address) self.number = number def show_info(self): # print("name:%s sex:%s, age:%") print(self.__dict__) def select_cursor(self): print("%s 正在选课...." % self.name) class Teacher(Person): def __init__(self,name,sex,age,salary,level,phonenumber,operator,address): super().__init__(name,sex,age,phonenumber,operator,address) self.salary = salary self.level = level def set_score(self): print("%s 正在为学生打分..." % self.name) # 上述代码通过继承减少了代码冗余 # 需要给学生添加手机这个属性,(手机号码,运营商,归属地,可以打电话) # 需要给学生添加电脑这个属性,(品牌,系统,CPU,内存,可以看视频,打游戏) # stu = Student("李寻欢","女",20,"飞刀一班","18666666666","中国移动","上海浦东") # print(stu.name) # print(stu.phonenumber)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 学生会增加各种各样的新的属性 比如手机 比如电脑, 这样Student中会增加大量的属性和方法 # 后期的维护成本非常高 # 这时就需要使用组合 来完成减少代码冗余 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("name:%s sex:%s, age:%") print(self.__dict__) def select_cursor(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() # 通过将手机对象和学生对象进行组合 完成了需求,并且相比较继承而言 # 耦合度低 手机和学生在修改的时候 互不影响 # 同时也减少了代码冗余
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
""" 用代码 描述乐队 一个乐队有其他多个乐器组成 主唱 乐队可以演奏歌曲 主唱是歌手类 会唱歌 ,有名字 钢琴类 能弹奏,有价格,牌子 """ class Band: def __init__(self,name,singer,piano): self.name = name self.singer = singer self.piano = piano def play_music(self): print("hello 我们%s 组合! 请欣赏" % self.name) self.singer.singing() self.piano.playing() class Singer: def __init__(self,name): self.name = name def singing(self): print("你好我是歌手 ",self.name) class Piano: def __init__(self,price,brand): self.price = price self.brand = brand def playing(self): print("正在弹琴.....") # 发现一个歌手 singer = Singer("王俊元") # 买一台钢琴 p = Piano("100","亚麻黑") # 组件乐队 b = Band("TFBoyss",singer,p) # 开演唱会 b.play_music()
三.封装
1.什么是封装?
简单的来说,在程序中,封装就是将内容隐藏起来。
封装:指的是隐藏内部实现的细节,对外部提供使用接口。
特点:被隐藏的内容,在内部可以直接访问,外部需要通过内部提供的接口才能访问。
2.为什么有封装?
1. 提高安全性(例:cpu频率、缓冲区大小、手机等)
对于封装属性而言,是通过给访问和修改增加额外的逻辑判断来实现的
2.明确区分内外部
(注:在python中的权限:公开、私有)
3.如何使用封装?
在属性或方法名前加双下划线,就可以实现隐藏。
属性的封装,通常需要提供相应的设置器(get_name())和访问器(set_name())
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Student: def __init__(self,name,sex,age,idCard): self.name = name self.age = age self.sex = sex self.__idCard = idCard 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.__idCard) # 可以使用方法 将内部封装的内容返回出去 def get_idCard(self): return self.__idCard # 如果直接返回的话 就没必要设置隐藏了 ,谁都可以通过调用方法来获取,我们再方法中加上自己的判断逻辑 def get_idCard2(self,pwd): # 如果密码正确我就给你身份证号码 if pwd == "1111": return self.__idCard else: print("滚 你没有资格知道我的身份证...") def set_idCard(self,pwd,new_idCard): # 如果密码正确就允许修改 if pwd == "1111": self.__idCard = new_idCard else: print("滚 你没有资格修改我的身份证...") stu = Student("步惊云","男",20,"3206661998445132") stu.say_hi() # print(stu.__idCard) # 加上__也访问不了 # stu.test() # 但在内部是可以访问的 # idcard = stu.get_idCard() # print(idcard) # 即实现了隐藏 又提供了访问的接口 这就是封装的用法 # idcard = stu.get_idCard2("1111") # print(idcard) # 身份证填错了 要修改 # stu.__idCard = "123" # 这样是无法修改原来的身份证信息的 而是添加了新的属性 # # print(stu.__idCard) # print(stu.get_idCard2("1111")) # 调用方法来修改隐藏的属性 stu.set_idCard("1111","xxxxxxxxxxxxxxxxxx") print(stu.get_idCard2("1111")) # 总结:对于被隐藏的属性 访问和修改都需要通过方法 get用于获取 set用于设置(也称之为设置器和访问器)