26 面向对象示例 封装

面向对象示例 封装

1 面向对象示例

1.1 需求

选课系统项目中涉及到诸多数据与功能,要求引入面向对象的思想对其进行高度整合

  1. 学校
  2. 班级
  3. 课程
1.2 学校

共有属性:学校名
独有属性:校区名,地址,班级
方法:添加班级,打印班级

class School:
	# 对象共有的属性
	full_name = 'Old Boy'  # 学校名
	
	# 定制对象独有的属性
	def __init__(self, name, addr):
		self.name = name  # 校区名
		self.addr = addr  # 校区地址
		self.class_list = []  # 校区的班级列表
		
	def add_class(self, class_obj):
		self.class_list.append(class_obj)

	def print_all_class_names(self):
		print(self.name)
		for each_obj in self.class_list:
			print(each_obj.name, end='\t')
	
	def print_all_course_names(self):
		print(self.name)
		for each_obj in self.class_list:
			each_obj.print_all_course_names()

	def print_all_course_details(self):
		print(self.name)
		for each_obj in self.course_list:
			each_obj.print_all_course_details()
1.3 班级

属性:班级名,课程
方法:添加课程,打印课程

class Class:
	def __init__(self, name):
		self.name = name
		self.course_list = []

	def add_course(self, course_obj):
		self.course_list.append(course_obj)
	
	def print_all_course_names(self):
		print(self.name)
		for each_obj in self.course_list:
			print(each_obj.name)
	
	def print_all_course_details(self):
		print(self.name)
		for each_obj in self.course_list:
			each_obj.print_course_detail()
1.4 课程

属性:课程名,周期, 价格
方法:打印课程信息

class Course:
	def __init__(self, name, circle, price):
		self.name = name
		self.circle = circle
		self.price = price

	def print_course_detail(self):
		print(self.name, self.circle, self.price)
1.5 造数据
tj_sch_obj = School('老男孩天津校区', '天津市河东区XX路XX号')
sh_sch_obj = School('老男孩上海校区', '上海市嘉定区XX路XX号')

tj1_cla_obj = Class('天津1期')
sh1_cla_obj = Class('上海1期')

tj1_sch_obj.add_class(tj1_cla_obj)
sh1_sch_obj.add_class(sh1_cla_obj)

ui1_course_obj = Course('UI设计1期', '3月', 18000)
cad2_course_obj = Course('CAD设计1期', '3月', 18000)
android1_course_obj = Course('安卓开发1期', '4月', 22000)
ios2_course_obj = Course('IOS开发1期', '4月', 22000)

tj1_cla_obj.add_class(ui1_class_obj)
tj1_cla_obj.add_class(cad1_class_obj)
sh1_cla_obj.add_class(android1_class_obj)
sh1_cla_obj.add_class(ios1_class_obj)

2 封装

2.1 封装的概念

封装是面向对象三大特性中的核心,封装的实质就是整合。

2.2 隐藏属性/方法

只在属性名或方法名前添加__前缀,表示这个属性或者方法是私有的,可以实现对外隐藏的效果。

class Demo:
    __x = 1

    def print_x(self):
        print(self.__x)  # 1
        print(self.__print_xx.__name__)  # __print_xx

    def __print_xx(self):
        print(self.__x)

demo_obj = Demo()
demo_obj.print_x()  # 1
# demo_obj.__print_xx()  # AttributeError: 'Demo' object has no attribute '__print_xx'
# demo_obj.__x  # AttributeError: 'Demo' object has no attribute '__x'
# Demo.__x  # AttributeError: type object 'Demo' has no attribute '__x'
print(Demo.__dict__)
# {'__module__': '__main__', '_Demo__x': 1, 'print_x': <function Demo.print_x at 0x000001B58BA764C0>, '__dict__': <attribute '__dict__' of 'Demo' objects>, '__weakref__': <attribute '__weakref__' of 'Demo' objects>, '__doc__': None}

demo_obj._Demo__x
Demo._Demo__x

demo_obj._Demo__print_xx()  # 1
  1. 在类外部无法直接访问拥有__前缀的属性和方法,但知道了类名和属性/方法名后可以通过名字 _类名__属性/方法 访问。所以这种操作并没有严格意义上地限制外部访问,仅仅只是名字变形。
  2. 在类内部是可以直接访问拥有__前缀的属性和方法的,因为在类定义阶段类内部拥有__前缀的属性/方法统一发生了名字变形。
  3. 变形操作只在类定义阶段发生一次,在类定义之后任何赋值操作都不会变形。
class Demo:
    __x = 1  # 发生名字变形

Demo.__y = 3  # 不会发生名字变形
demo_obj = Demo()
print(demo_obj._Demo__x)  # 1
print(demo_obj.__y)  # 3
2.3 使用方法
  1. 隐藏属性
    将数据隐藏起来就限制了类外部对数据的直接操作,然后类内应该提供相应的接口来允许类外部间接地操作数据。
    作为类的设计者,可以在接口函数上添加逻辑代码来控制使用者对类属性的访问和修改。
class Person:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def get_name(self):
        return self.__name

    def get_age(self):
        return self.__age

    def set_age(self, age):
    	if type(age) is not int:
    		print('年龄只接受整数。')
        else:
        	self.__age = age

p_obj1 = Person('王长贵', 25)
print(p_obj1.get_name())  # 王长贵
p_obj1.set_age(26)
print(p_obj1.get_age())  # 26
  1. 隐藏方法
    目的的是为了隔离复杂度。
    例如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()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值