Loading

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()
posted @ 2021-12-05 17:09  maju  阅读(21)  评论(0)    收藏  举报