python 之 面向对象基础(组合和封装)
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 之 面向对象基础(组合和封装)的更多相关文章
- python开发面向对象基础:封装
一,封装 [封装] 隐藏对象的属性和实现细节,仅对外提供公共访问方式. [好处] 1. 将变化隔离: 2. 便于使用: 3. 提高复用性: 4. 提高安全性: [封装原则] 1. 将不需要对外提供的内 ...
- Java第三次作业——面向对象基础(封装)
Java第三次作业--面向对象基础(封装) (一)学习总结 1.什么是面向对象的封装性,Java中是如何实现封装性的?试举例说明. 封装性 封装性是面向对象的方法所应遵循的一个重要原则,它有两个含义: ...
- day020|python之面向对象基础2
面向对象基础2 目录 面向对象基础2 7 对象与类型 7.1 类即类型 7.1.1 变量的三个指标 7.1.2 变量类型 7.2 list.append()方法原理 8 对象的高度整合 8.1 通过面 ...
- Python全栈--9 __import__ 反射和面向对象基础 self 封装 继承(多继承的顺序) 多态
一.反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删 ...
- python基础-9__import__ 反射和面向对象基础 self 封装 继承(多继承顺序) 多态
一 反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删 ...
- PYTHON开发--面向对象基础入门
面向对象 一:面向对象初级 1.思考:首先在python中,以前我们以前用到的几乎都是函数式编程,但是有时候函数式编程其中代码重复利用率太高,我们往往会把这些重复代码写进一个函数日后去调用,所以呢,今 ...
- PYTHON开发--面向对象基础二
一.成员修饰符 共有成员 私有成员, __字段名 - 无法直接访问,只能间接访问 1. 私有成员 1.1 普通方法种的私有成员 class Foo: def __init__(self, n ...
- python开发面向对象基础:接口类&抽象类&多态&钻石继承
一,接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实 ...
- Python:面向对象基础
基本理论 什么是对象 万物皆对象 对象是具体的事物 拥有属性.行为 把许多零散的东西,封装成为一个整体 Python中一切东西都是对象,Python是一门特别彻底的面向对象编程语言(OOP) 其他编程 ...
随机推荐
- SyntaxError: Non-ASCII character 'æ' in file csdn.py on line 7, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
错误信息: SyntaxError: Non-ASCII character , but no encoding declared; see http://python.org/dev/peps/pe ...
- go中的方法以及自定义类型代码示例
package main import "fmt" type user struct { name string age int sex string } type admin s ...
- ubuntu之路——day8.2 深度学习优化算法之指数加权平均与偏差修正,以及基于指数加权移动平均法的动量梯度下降法
首先感谢吴恩达老师的免费公开课,以下图片均来自于Andrew Ng的公开课 指数加权平均法 在统计学中被称为指数加权移动平均法,来看下面一个例子: 这是伦敦在一些天数中的气温分布图 Vt = βVt- ...
- appium+python 微信小程序的自动化
sudo kill -9 $(lsof -i:8889 -t) mitmweb -p 8889 -s addons.py mitmdump -q -p 8889 -s addons.py http: ...
- qt creator中常用快捷键
激活欢迎模式 Ctrl + 1 激活编辑模式 Ctrl + 2 激活调试模式 Ctrl + 3 激活项目模式 Ctrl + 4 激活帮助模式 Ctrl + 5 激活输出模式 Ctrl + 6 查找当前 ...
- Learning to rank基本算法
搜索排序相关的方法,包括 Learning to rank 基本方法 Learning to rank 指标介绍 LambdaMART 模型原理 FTRL 模型原理 Learning to rank ...
- python命令行传入参数
1.sys import sys a=eval(sys.argv[1])b=eval(sys.argv[2]) print(a+b) 1 2 3 4 5 6 evel() ...
- 钉钉通知机器人与SpringBoot的集成
Spring Boot Admin 集成自定义监控告警(2.0.1版本)------钉钉机器人 - yuancao24的博客 - CSDN博客https://blog.csdn.net/yuancao ...
- net.ipv4.tcp_fin_timeout的错误理解
按照文档的说法,貌似长久以来我对于tcp_fin_timeout的理解都是错误的 先备份在这里,再验证 提高Linux应对短连接的负载能力 在存在大量短连接的情况下,Linux的TCP栈一般都 ...
- Mysql的三种数据类型
Mysql的三种数据类型 1.数值类型 2.日期和时间类型 3.字符串类型 00x1 [数值类型] 00x2 [日期和时间类型] 00x3 [字符串类型]