7.4 组合

解决类与类之间代码冗余问题有两种解决方案:

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) #创建老师类的对象tea1
date_obj=Date(2000,1,1) #创建Date类的对象date_obj
date_obj.tell_birth() #date_obj可以调用绑定方法tell_birth

tea1.birth=date_obj #tea1的birth属性来自于Date类的一个对象date_obj
tea1.birth.tell_birth() #tea1的birth属性可以调用tell_birth属性
stu1=Oldboystudent('张三',16,'male','linux')
stu1.birth=Date(2002,3,3)
stu1.birth.tell_birth()
stu1.choose() #使用stu1将两个类联系起来

7.5 封装

什么是封装: 装就是把一堆属性存起来,封的概念就把这些属性给隐藏起来,其实这种隐藏只是一种语法上的变形,对外不对内

注意:

为一个属性名加__开头(注意不要加__结尾),会在类定义阶段将属性名统一变形:_自己的类名__属性名

class Foo:
x=1
__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) # 1
print(obj.__x) # 报错
print(obj._Foo__x) #

obj.__f1() #报错
obj._Foo__f1() # Foo.f1

print(obj.y) #报错
print(obj.__y) #报错
print(obj._Foo__y) #
obj.get_y() # 22222 明确地区分内外,对外是隐藏的,对内是开放的

这种语法意义上变形,只在类定义阶段发生一次,类定义之后,新增的__开头的属性都没有变形的效果

Foo.__aaa=1
print(obj.__aaa) # 1

如果父类不想让子类覆盖自己的方法,可以在方法名前加__开头

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() # Foo.f2 Foo.f1

7.51 封装的作用

封装数据属性的目的:

把数据属性封装起来,然后需要开辟接口给类外部的使用者使用,好处是我们可以在接口之上添加控制逻辑,从而严格空间访问者对属性的操作

class People:
def __init__(self,name):
self.__name=name

def tell_name(self):
# 添加逻辑
return self.__name obj=People('egon')
#obj.__name
obj.tell_name()

封装函数属性的目的:为了隔离复杂度

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()

7.52 封装之property

用来将类内的函数伪装成一个数据属性

例:

体质指数()体重()身高()

  首先需要明确 : bmi是算出来的,不是一个固定死的值,也就说我们必须编写一个功能,每次调用该功能 都会立即计算一个值

class People:
def __init__(self,name,weight,height):
self.name=name
self.weight=weight
self.height=height

@property #于是我们需要为bmi这个函数添加装饰器,将其伪装成一个数据属性
def bmi(self):
return self.weight / (self.height * self.height) egon=People('egon',75,1.80)
yl=People('yangli',85,1.74)
# print(egon.bmi())
# print(yl.bmi())

print(egon.bmi) # 21.604938271604937,调用egon.bmi本质就是触发函数bmi的执行,从而拿到其返回值
print(yl.bmi) # 把功能伪装成一个属性

@name.setter 和 @name.deleter

# egon.bmi=123
# egon.bmi背后对应的是一个函数,所以不能赋值
class People:
def __init__(self,name):
self.__name=name

@property
def name(self):
# 添加逻辑
return self.__name

@name.setter
def name(self,x):
# 添加逻辑
self.__name=x

@name.deleter
def name(self):
# 添加逻辑
del self.__name

obj=People('egon')
print(obj.name) # egon
# 修改
obj.name='EGON' # 现在可以赋值
print(obj.name) # EGON

del obj.name # 删除

obj.name # 报错

最新文章

  1. [C#.net] SendMessage
  2. seo伪原创技术原理分析,php实现伪原创示例
  3. magento在产品详细页面添加分享链接的方法
  4. asp web api 怎么使用put和delete。
  5. jackson 注解的使用
  6. SilkTest Q&amp;A 8
  7. JSOI2015 一轮省选 个人题解与小结
  8. oracle 树形表结构查询 排序
  9. js中数学运算的处理
  10. linux jdk 和tomcat环境变量配置
  11. php实现微信企业向用户付款
  12. SSH整合Maven教程
  13. php password_hash
  14. Nginx + Tomcat 在 Windows7 上搭建负载均衡集群
  15. BZOJ.3510.首都(LCT 启发式合并 树的重心)
  16. ScrollReveal.js 用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力。
  17. Spring MVC统一异常处理
  18. Python学习笔记 - 实现探测Web服务质量
  19. Tomcat下JSP、Servlet和JavaBean环境的配置
  20. Postgresql 创建账户,修改密码

热门文章

  1. ICEM-闪闪的党徽
  2. arts 打卡12周
  3. Mysql 查看所有线程,被锁的表
  4. Guided Hacking DLL Injector 3.3
  5. MFC GDI+显示GIF文件《转》
  6. HttpWebRequest Timeout
  7. chrome 等浏览器不支持本地ajax请求,的问题
  8. 官方Android Camera2 录像示例--停止录像时崩溃修正
  9. layer.msg 弹出不同的效果的样式
  10. Typora 精美而强大的Markdown编辑器