day 28 封装
1 封装
1.1 封装介绍
面向对象编程有三大特性:封装、继承、多态,其中最重要的一个特性就是封装。封装指的就是把数据与功能都整合到一起,听起来是不是很熟悉,没错,我们之前所说的”整合“二字其实就是封装的通俗说法。除此之外,针对封装到对象或者类中的属性,我们还可以严格控制对它们的访问,分两步实现:隐藏与开放接口
封装是面向对象三大特性最核心的一个特性
封装<<<---->>>整合
1.2 将封装的属性进行隐藏操作
1.2.1 隐藏操作
如何隐藏
在属性名前加 _ _ 前缀,就会实现一个对外隐藏属性效果
该隐藏需要注意的问题
I:在类外部无法直接访问双下滑线开头的属性,但知道了类名和属性名就可以拼出名字: _ 类名_ _ 属性,然后就可以访问了,如 Foo._ A _ _N,所以说这种操作并没有严格意义上地限制外部访问,仅仅只是一种语法意义上的变形。
class Foo:
__x = 1 # _Foo__x
def __f1(self): # _Foo__ f1
print('from test')
print(Foo.__dict__)
print(Foo._Foo__x)
print(Foo._Foo__f1)
II:这种隐藏对外不对内,因为__开头的属性会在检查类体代码语法时统一发生变形
class Foo:
__x = 1 # _Foo__x = 1
def __f1(self): # _Foo__f1
print('from test')
def f2(self):
print(self.__x) # print(self._Foo__x)
print(self.__f1) # print(self._Foo__f1)
print(Foo.__x)
print(Foo.__f1)
obj=Foo()
obj.f2()
III: 这种变形操作只在检查类体语法的时候发生一次,之后定义的 __开头的属性都不会变形
class Foo:
__x = 1 # _Foo__x = 1
def __f1(self): # _Foo__f1
print('from test')
def f2(self):
print(self.__x) # print(self._Foo__x)
print(self.__f1) # print(self._Foo__f1)
Foo.__y=3
print(Foo.__dict__)
print(Foo.__y)
class Foo:
__x = 1 # _Foo__x = 1
def __init__(self,name,age):
self.__name=name
self.__age=age
obj=Foo('egon',18)
print(obj.__dict__)
print(obj.name,obj.age)
1.2.2为何要隐藏?
定义属性就是为了使用,所以隐藏并不是目的
隐藏数据属性
将数据隐藏起来就限制了类外部对数据的直接操作,然后类内应该提供相应的接口来允许类外部间接地操作数据,接口之上可以附加额外的逻辑来对数据的操作进行严格地控制:
设计者:egon
class People:
def __init__(self, name):
self.__name = name
def get_name(self):
#通过该接口就可以间接地访问到名字属性
print('小垃圾,不让看')
print(self.__name)
def set_name(self,val):
if type(val) is not str:
print('小垃圾,必须传字符串类型')
return
self.__name=val
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
使用者:王鹏
obj = People('egon')
print(obj.name) # 无法直接用名字属性
obj.set_name('EGON')
obj.set_name(123123123)
obj.get_name()
隐藏函数/方法属性
目的的是为了隔离复杂度。目的的是为了隔离复杂度,例如ATM程序的取款功能,该功能有很多其他功能组成,比如插卡、身份认证、输入金额、打印小票、取钱等,而对使用者来说,只需要开发取款这个功能接口即可,其余功能我们都可以隐藏起来
>>> class ATM:
... def __card(self): #插卡
... print('插卡')
... def __auth(self): #身份认证
... print('用户认证')
... def __input(self): #输入金额
... print('输入取款金额')
... def __print_bill(self): #打印小票
... print('打印账单')
... def __take_money(self): #取钱
... print('取款')
... def withdraw(self): #取款功能
... self.__card()
... self.__auth()
... self.__input()
... self.__print_bill()
... self.__take_money()
...
>>> obj=ATM()
>>> obj.withdraw()
2 班级类
整合->解耦合->扩展性增强
点击查看代码
一:学校
class School:
school_name = 'OLDBOY'
def __init__(self, nickname, addr):
self.nickname = nickname
self.addr = addr
self.classes = []
def related_class(self, class_obj):
self.classes.append(class_obj)
def tell_class(self):
#打印的班级的名字
print(self.nickname.center(60,'='))
#打印班级开设的课程信息
for class_obj in self.classes:
class_obj.tell_course()
1、创建校区
school_obj1=School('老男孩魔都校区','上海')
school_obj2=School('老男孩帝都校区','北京')
2、为学校开设班级
上海校区开了:脱产 14 期,上海校区开了脱产 15 期
school_obj1.related_class("脱产 14 期")
school_obj1.related_class("脱产 15 期")
北京校区开了:脱产 29 期
school_obj2.related_class("脱产 29 期")
3、查看每个校区开设的班级
school_obj1.tell_class()
school_obj2.tell_class()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
二:班级
class Class:
def __init__(self, name):
self.name = name
self.course = None
def related_course(self, course_obj):
self.course = course_obj
def tell_course(self):
print('%s' % self.name,end=" ")
self.course.tell_info() # 打印课程的详细信息
1、创建班级
class_obj1 = Class('脱产 14 期')
class_obj2 = Class('脱产 15 期')
class_obj3 = Class('脱产 29 期')
2、为班级关联一个课程
class_obj1.related_course('python 全栈开发')
class_obj2.related_course('linux 运维')
class_obj3.related_course('python 全栈开发')
3、查看班级开设的课程信息
class_obj1.tell_course()
class_obj2.tell_course()
class_obj3.tell_course()
4、为学校开设班级
上海校区开了:脱产 14 期,上海校区开了脱产 15 期
school_obj1.related_class(class_obj1)
school_obj1.related_class(class_obj2)
北京校区开了:脱产 29 期
school_obj2.related_class(class_obj3)
school_obj1.tell_class()
school_obj2.tell_class()class Course:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
三:课程
class Course:
def __init__(self,name,period,price):
self.name=name
self.period=period
self.price=price
def tell_info(self):
print('<课程名:%s 周期:%s 价钱:%s>' %(self.name,self.period,self.price))
1、创建课程
course_obj1=Course('python 全栈开发','6mons',20000)
course_obj2=Course('linux 运维','5mons',18000)
2、查看课程的详细信息
course_obj1.tell_info()
course_obj2.tell_info()
3、为班级关联课程对象
class_obj1.related_course(course_obj1)
class_obj2.related_course(course_obj2)
class_obj3.related_course(course_obj1)
class_obj1.tell_course()
class_obj2.tell_course()
class_obj3.tell_course()
school_obj1.tell_class()
school_obj2.tell_class()

浙公网安备 33010602011771号