4月13日 python学习总结 组合与封装
2024-09-08 07:21:37
一、组合
解决类与类之间代码冗余问题有两种解决方案:1、继承 2、组合
1、继承:描述的是类与类之间,什么是什么的关系
2、组合:描述的是类与类之间的关系,是一种什么有什么关系
一个类产生的对象,该对象拥有一个属性,这个属性的值是来自于另外一个类的对象
class Date:
def __init__(self,year,mon,day):
self.year = year
self.mon = mon
self.day = day def tell_birth(self):
print('出生年月日<%s-%s-%s>' % (self.year, self.mon, self.day)) class OldboyPeople:
school = 'oldboy' def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,level,salary):
super().__init__(name,age,sex)
self.level=level
self.salary=salary def change_score(self):
print('teacher %s is changing score' %self.name) class Oldboystudent(OldboyPeople):
def __init__(self,name,age,sex,course,):
super().__init__(name,age,sex,)
self.course=course def choose(self):
print('student %s choose course' %self.name) tea1=OldboyTeacher('egon',18,'male',9,3.1)
date_obj=Date(2000,1,1)
# date_obj.tell_birth() tea1.birth=date_obj
# print(tea1.birth)
# tea1.birth.tell_birth()
# tea1.change_score() stu1=Oldboystudent('张三',16,'male','linux')
stu1.birth=Date(2002,3,3)
stu1.birth.tell_birth()
二、封装
1、什么是封装
装就是把一堆属性存起来,封的概念就把这些属性给隐藏起来
强调:封装单从字面意思去看等同于隐藏,但其实封装绝对不是单纯意义的隐藏
2、为什么要用封装
封装数据属性的目的:把数据属性封装起来,然后需要开辟接口给类外部的使用者使用,好处是
我们可以在接口之上添加控制逻辑,从而严格空间访问者对属性的操作class People:
def __init__(self,name,age):
self.__name=name
self.__age=age def tell_info(self):
# u=input('user>>: ').strip()
# p=input('pwd>>: ').strip()
# if u == 'egon' and p == '123':
print(self.__name,self.__age) def set_info(self,name,age):
if type(name) is not str:
raise TypeError('用户名必须为str类型')
if type(age) is not int:
raise TypeError('年龄必须为int类型')
self.__name=name
self.__age=age p=People('egon',18) # p.tell_info()
# p.tell_info() # p.set_info('EGON',19)
# p.tell_info() # p.set_info(353535353535353535,20)
p.set_info('EGON','20')- 封装函数属性的目的:为了隔离复杂度
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()
3. 封装的终极奥义:明确地区分内外,对外是隐藏的,对内是开放的
3、如何用封装
其实这种隐藏只是一种语法上的变形,对外不对内
为一个属性名加__开头(注意不要加__结尾),会在类定义阶段将属性名统一变形:_自己的类名__属性名class Foo:
__x=1111 #_Foo__x=1111
def __init__(self,y):
self.__y=y #self._Foo__y=y def __f1(self): #_Foo__f1
print('Foo.f1') def get_y(self):
print(self.__y) # print(self._Foo__y) obj=Foo(22222)
# print(obj.x)
# print(obj.__x)
# obj.__f1()
# print(obj.y)
# print(obj.__y)
# print(Foo.__dict__)
# print(obj._Foo__x)
# print(obj._Foo__y)
# obj._Foo__f1() # obj.get_y()
- 这种语法意义上变形,只在类定义阶段发生一次,类定义之后,新增的__开头的属性都没有变形的效果
- 如果父类不想让子类覆盖自己的方法,可以在方法名前加__开头
class Foo:
def __f1(self): #_Foo__f1
print('Foo.f1') def f2(self):
print('Foo.f2')
self.__f1() #obj._Foo__f1() class Bar(Foo):
def __f1(self): #_Bar__f1
print("Bar.f1") obj=Bar() obj.f2()
最新文章
- monkeyrunner API接口文档内容
- Visual studio智能感知挡住了当前代码输入行
- Windows MFC 两个OpenGL窗口显示与线程RC问题
- 【高级功能】使用Web存储
- BZOJ2990 : [Ontak2010]Keyboard
- javascript事件之:谈谈自定义事件
- Etl之HiveSql调优(设置map reduce 的数量)
- linq 动态组合条件
- 一键制作u盘启动盘教程
- Java-->;在txt文件每一行前加行数和冒号
- Telnet RFC
- 关于win7系统的Oracle安装时的[INS-30131]问题的解决方案
- ASP.NET - cookie
- 【干货】Markdown编辑博文,公式图片轻松搞定
- C. A Mist of Florescence
- Win7 x64 svn 服务器搭建
- iOS学习笔记之异步图片下载
- Vue学习记录(一)
- Oracle EBS OPM reshedule batch
- UML:概要设计,用什么画我的类图?
热门文章
- 描述nginx中worker_processes、worker_cpu_affinity、worker_rlimit_nofile、worker_connections配置项的含义
- 使用代码绑定 DataGridView 控件用于程序界面显示表格
- Linux常用命令在Ubuntu 16下(个人笔记)
- 5.Flink实时项目之业务数据准备
- 我们一起来学Shell - shell的并发及并发控制
- if,for,while,do...while
- MySQL架构原理之存储引擎InnoDB数据文件
- CentOS8上安装MySQL
- vue实例中的watch属性
- NSSCTF-[UTCTF 2020]Zero