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) 其他编程 ...
随机推荐
- OpenFOAM设置监测点(探针)
首先准备好我们自己的平常算例文件,本次我们以圆柱绕流的算例来说明用法 然后我们在/opt/openfoam4/etc/caseDicts/postProcessing/probes文件夹下找到prob ...
- java读取文件内容并输出到控制台,java中实现文件复制
public class TestFileInputStream { public static void main(String [] args) { //读取指定文件中内容,并在控制台输出 Fil ...
- Azure存储简介
注:此篇文档主要讲述微软azure全球版,并不完全试用azure中国区 azure存储是Microsoft一项托管服务,提供的云存储的可用性.安全性.持久性.可伸缩性和冗余都很高,azure存储包 ...
- Visual Studio、.NET Framework、VC++、C#各个版本的对应关系
Visual Studio..NET Framework.VC++.C#各个版本的对应关系 Visual Studio版本 .NET Framework版本 内部版本 VC++版本 C#版本 Visu ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第9节 SpringBoot2.x整合Redis实战_37、分布式缓存Redis介绍
笔记 1.分布式缓存Redis介绍 简介:讲解为什么要用缓存和介绍什么是Redis,新手练习工具 1.redis官网 https://redis.io/download ...
- 海思3531添加移远EC20 4g模块(转)
源: 海思3531添加移远EC20 4g模块 Hi3798移植4G模块(移远EC20)
- 海思uboot启动流程详细分析(转)
海思uboot启动流程详细分析(一) 海思uboot启动流程详细分析(二) 海思uboot启动流程详细分析(三)
- mac PHP安装imageMagic扩展
1. 安装:ImageMagick:命令:brew install ImageMagick这种方式安装下来的imageMagic,不缺少东西,报错较少.安装之后的位置:/usr/local/Cella ...
- iptables nat表配置
- fkutter Stepper步骤指示器
一个Material Design 步骤指示器,显示一系列步骤的过程 import 'package:flutter/material.dart'; class StepperDemo extends ...