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 # 报错

python 之 面向对象基础(组合和封装)的更多相关文章

  1. python开发面向对象基础:封装

    一,封装 [封装] 隐藏对象的属性和实现细节,仅对外提供公共访问方式. [好处] 1. 将变化隔离: 2. 便于使用: 3. 提高复用性: 4. 提高安全性: [封装原则] 1. 将不需要对外提供的内 ...

  2. Java第三次作业——面向对象基础(封装)

    Java第三次作业--面向对象基础(封装) (一)学习总结 1.什么是面向对象的封装性,Java中是如何实现封装性的?试举例说明. 封装性 封装性是面向对象的方法所应遵循的一个重要原则,它有两个含义: ...

  3. day020|python之面向对象基础2

    面向对象基础2 目录 面向对象基础2 7 对象与类型 7.1 类即类型 7.1.1 变量的三个指标 7.1.2 变量类型 7.2 list.append()方法原理 8 对象的高度整合 8.1 通过面 ...

  4. Python全栈--9 __import__ 反射和面向对象基础 self 封装 继承(多继承的顺序) 多态

    一.反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删 ...

  5. python基础-9__import__ 反射和面向对象基础 self 封装 继承(多继承顺序) 多态

    一 反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删 ...

  6. PYTHON开发--面向对象基础入门

    面向对象 一:面向对象初级 1.思考:首先在python中,以前我们以前用到的几乎都是函数式编程,但是有时候函数式编程其中代码重复利用率太高,我们往往会把这些重复代码写进一个函数日后去调用,所以呢,今 ...

  7. PYTHON开发--面向对象基础二

    一.成员修饰符 共有成员 私有成员, __字段名 - 无法直接访问,只能间接访问 1.     私有成员 1.1  普通方法种的私有成员 class Foo: def __init__(self, n ...

  8. python开发面向对象基础:接口类&抽象类&多态&钻石继承

    一,接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实 ...

  9. Python:面向对象基础

    基本理论 什么是对象 万物皆对象 对象是具体的事物 拥有属性.行为 把许多零散的东西,封装成为一个整体 Python中一切东西都是对象,Python是一门特别彻底的面向对象编程语言(OOP) 其他编程 ...

随机推荐

  1. ManualResetEven使用的最清楚说明

    ManualResetEven使用的最清楚说明 快速阅读 理解ManualResetEvent,以及如何使用. 官方说明 官方介绍:https://docs.microsoft.com/en-us/d ...

  2. js中引入js

    第一个js文件(被引入的js文件),文件名one.js,内容如下 function alertInOne(){    alert('in one');} 第二个js文件,文件名two.js,内容如下 ...

  3. mysql innodb与myisam存储文件的区别

    myisam: .frm: 存储表定义 .myd(MYData):存储数据 .MYI(MYindex):存储引擎 innodb: .frm:存储表定义 .idb:存储数据和索引,在同一个文件中

  4. TL-WR941N路由器刷DD-WRT和OPENWRT教程及使用花生壳

    今天没事做,于是决定把自己的TL-WR941N路由器刷成OPENWRT系统的.虽然说没买小米路由,但是刷成OPENWRT系统的话还是能增强不少的功能.下面写出经过一下午折腾的详细安装步骤,同样适用于其 ...

  5. JAVA基础之访问控制权限

    包:库单元 1.当编写一个Java源代码文件时,此文件通常被称为编译单元(有时也被称为转译单元). 2.每个编译单元都必须有一个后缀名.java,而在编译单元内则可以有一个public类,该类名称必须 ...

  6. sql中order by和group by的区别

    order by 和 group by 的区别: 1,order by 从英文里理解就是行的排序方式,默认的为升序. order by 后面必须列出排序的字段名,可以是多个字段名. 2,group b ...

  7. firewalld 实现nat 转发外网转发到内网 实现访问外网端口到内网

    第0步骤:  开启转发生效 [root@node178.oldboy.com ~]# cat /proc/sys/net/ipv4/ip_forward1 [root@node178.oldboy.c ...

  8. Mybatis Hibernate MiniDao 共存

    Mybatis MiniDao共存问题 - 国内版 Binghttps://cn.bing.com/search?q=Mybatis+MiniDao%E5%85%B1%E5%AD%98%E9%97%A ...

  9. 树莓派 more

    树莓派 rusthttps://tech.iotcomeon.com/2018/06/tech/deploy/515/sudo curl https://sh.rustup.rs -sSf | sh ...

  10. ansible常用的方法小结

    一.批量安装zabbix客户端 .拷贝sh脚本和.conf到远程服务器(也可以全量拷贝客户端) ansible all -m copy -a "src=/usr/local/zabbix_a ...