Python 面向对象 组合-多态与多态性-封装-property
面向对象-组合
1.什么是组合
组合指的是某一个对象拥有一个属性,该属性的值是另外一个类的对象
class Foo:
xxx = 111 class Bar:
yyy = 222 obj = Foo()
obj.attr = Bar() print(obj.xxx)
>>>111
print(obj.attr.yyy)
>>>222
2.为何要用组合
通过为某一个对象添加属性(属性的值是另外一个类的对象)的方式,可以间接地将两个类关联/整合/组合到一起
从而减少类与类之间代码冗余
class Foo1:
pass
class Foo2:
pass
class Foo3:
pass class Bar:
pass obj_from_bar=Bar() obj1=Foo1()
obj2=Foo2()
obj3=Foo3() obj1.attr1=obj_from_bar
obj2.attr2=obj_from_bar
obj3.attr3=obj_from_bar
3.如何用组合
class OldboyPeople:
school = 'Oldboy' def __init__(self, name, age, sex, ):
self.name = name
self.age = age
self.sex = sex class OldboyStudent(OldboyPeople):
def __init__(self, name, age, sex, score=0):
OldboyPeople.__init__(self, name, age, sex)
self.score = score
self.courses = [] def choose_course(self):
print('%s choosing course' % self.name) def tell_all_course(self):
print(('学生[%s]选修的课程如下' % self.name).center(50, '='))
for obj in self.courses:
obj.tell_info()
print('=' * 60) class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, sex, level):
OldboyPeople.__init__(self, name, age, sex)
self.level = level
self.courses = [] def score(self, stu, num):
stu.score = num def tell_all_course(self):
print(('老师[%s]教授的课程如下' % self.name).center(50, '*'))
for obj in self.courses:
obj.tell_info()
print('*' * 70) class Course:
def __init__(self, c_name, c_price, c_period):
self.c_name = c_name
self.c_price = c_price
self.c_period = c_period def tell_info(self):
print('<课程名:%s 价钱:%s 周期:%s>' % (self.c_name, self.c_price, self.c_period)) # 创建课程对象
python = Course('python全栈开发', 1900, '5mons')
linux = Course('linux架构师', 900, '3mons') stu1 = OldboyStudent('刘二蛋', 38, 'male')
stu1.courses.append(python)
stu1.courses.append(linux)
stu1.tell_all_course() tea1 = OldboyTeacher('egon', 18, 'male', 10)
tea1.courses.append(python)
tea1.tell_all_course()
面向对象-多态与多态性
1.什么是多态
多态指的是同一种/类事物的不同形态
2.为何要用多态
多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象
3.如何用多态
Animal() #父类只是用来建立规范的,不能用来实例化,更无需实现内部的方法
import abc class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def speak(self):
pass @abc.abstractmethod
def run(self):
pass class People(Animal):
def speak(self):
print('say hello') def run(self):
pass class Dog(Animal):
def speak(self):
print('汪汪汪') def run(self):
pass class Pig(Animal):
def speak(self):
print('哼哼哼') def run(self):
pass obj1 = People()
obj2 = Dog()
obj3 = Pig()
Python推崇的是鸭子类型,只要你叫的声音像鸭子,并且你走路的样子也像鸭子,那你就是鸭子
class Disk:
def read(self):
print('Disk read') def write(self):
print('Disk write') class Memory:
def read(self):
print('Mem read') def write(self):
print('Mem write') class Cpu:
def read(self):
print('Cpu read') def write(self):
print('Cpu write') obj1 = Disk()
obj2 = Memory()
obj3 = Cpu() obj1.read()
obj2.read()
obj3.read()
面向对象-封装
1.什么是封装
装: 往容器/名称空间里存入名字
封: 代表将存放于名称空间中的名字给藏起来,这种隐藏对外不对内
2.为何要封装
封装数据属性:
将数据属性隐藏起来,类外就无法直接操作属性,需要类内部开辟一个接口,让外部的使用可以间接地操作属性,可以在接口内定制任意的控制逻辑,从而严格控制使用者对属性的操作
class People:
def __init__(self, name, age):
self.__name = name
self.__age = age def tell_info(self):
print('<name:%s age:%s>' % (self.__name, self.__age)) def set_info(self, name, age):
if type(name) is not str:
print('名字必须是str类型傻叉')
return
if type(age) is not int:
print('年龄必须是int类型傻叉')
return
self.__name = name
self.__age = age obj = People('egon', 18)
obj.set_info('EGON', '')
obj.tell_info()
封装函数属性: 隔离复杂度
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() a = ATM()
a.withdraw()
3.如何封装
在类内定义的属性前加__开头(没有__结尾)
总结:
1. __开头的属性实现的隐藏仅仅只是一种语法意义上的变形,并不会真的限制类外部的访问
2. 该变形操作只在类定义阶段检测语法时发生一次,类定义阶段之后新增的__开头的属性并不会变形
3. 如果父类不想让子类覆盖自己的属性,可以在属性前加__开头
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() >>>Foo.f2
>>>Foo.f1
面向对象-property
property装饰器是用来将类内的函数属性伪装成数据属性
class People:
def __init__(self, name):
self.__name = name @property
def name(self):
return '<名字:%s>' % self.__name @name.setter
def name(self, obj):
if type(obj) is not str:
print('name必须为str类型')
return
self.__name = obj @name.deleter
def name(self):
print('不让删') obj = People('egon')
del obj.name
print(obj.__dict__)
Python 面向对象 组合-多态与多态性-封装-property的更多相关文章
- python 面向对象:多态和多态性
很多人喜欢将多态与多态性二者混为一谈,然后百思不得其解,其实只要分开看,就会很明朗. 一.多态 多态指的是一类事物有多种形态.(一个抽象类有多个子类,因而多态的概念依赖于继承) 比如动物有多种形态:人 ...
- Python之路【第十篇】:Python面向对象之多态、多态性
阅读目录 一 多态 多态指的是一类事物有多种形态 动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.ABCMeta): #同一类事物:动物 @ab ...
- Py修行路 python基础 (十六)面向对象编程的 继承 多态与多态性 封装
一.继承顺序: 多继承情况下,有两种方式:深度优先和广度优先 1.py3/py2 新式类的继承:在查找属性时遵循:广度优先 继承顺序是多条分支,按照从左往右的顺序,进行一步一步查找,一个分支走完会走另 ...
- Python 面向对象的三大特性:封装,继承,多态
# 面向对象的三大特性:封装,继承,多态 # 继承的影响:资源的继承,资源的使用,资源的覆盖,资源的累加 # 资源的继承,在Python中的继承是指能使用父类的资源,而不是说在子类也复制一份父类代码到 ...
- python 面向对象之多态与绑定方法
多态与多态性 一,多态 1,多态指的是一类事物有多种形态(python里面原生多态) 1.1动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.AB ...
- Python面向对象之多态
多态 面向对象三大特性 封装 根据职责将属性和方法封装到一个抽象的类中:--定义类的准则 继承 实现代码的重用,相同的代码不需要重复的编写:--设计类的技巧:子类针对自己的需求,编写特定的代码: 多态 ...
- Python 面向对象5 多态
一.多态 多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作,简单的说就是一句话:允许将 ...
- python基础之多态与多态性、绑定方法和非绑定方法
多态与多态性 多态 多态并不是一个新的知识 多态是指一类事物有多种形态,在类里就是指一个抽象类有多个子类,因而多态的概念依赖于继承 举个栗子:动物有多种形态,人.狗.猫.猪等,python的序列数据类 ...
- python中对多态和多态性的理解
python中对多态的理解 一.多态 多态是指一类事物有多种形态,比如动物类,可以有猫,狗,猪等等.(一个抽象类有多个子类,因而多态的概念依赖于继承) import abc class Animal( ...
随机推荐
- 476. Number Complement(补数)
Given a positive integer, output its complement number. The complement strategy is to flip the bits ...
- bzoj 4385: [POI2015]Wilcze doły【单调栈】
对于每个i,以它为左端点的最优右端点一定是单增的,所以用单调栈维护 具体的,单调栈里放的是和单调的长为d的子段,然后枚举右端点,如果这段的和-当前长为d子段最大的和大于p的话,左端点右移同时注意单调栈 ...
- bzoj 4037: [HAOI2015]数字串拆分【dp+矩阵加速】
首先f长得就很像能矩阵优化的,先构造转移矩阵(这里有一点神奇的地方,我看网上的blog和我构造的矩阵完全不一样还以为我的构造能力又丧失了,后来惊奇的发现我把那篇blog里的构造矩阵部分换成我的构造方式 ...
- bzoj 4184: shallot【线性基+时间线段树】
学到了线段树新姿势! 先离线读入,根据时间建一棵线段树,每个节点上开一个vector存这个区间内存在的数(使用map来记录每个数出现的一段时间),然后在线段树上dfs,到叶子节点就计算答案. 注意!! ...
- bzoj 3589: 动态树【树链剖分+容斥】
因为一开始调试不知道unsigned怎么输出就没有加\n结果WA了一上午!!!!!然而最后放弃了unsigned选择了&2147483647 首先链剖,因为它所给的链一定是某个点到根的路径上的 ...
- luogu P1309 瑞士轮【排序】
题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低,但比赛过程往往十分 ...
- c语言程序设计案例教程(第2版)笔记(三)—变量、结构体
零散知识点: 变量 :C语言中,每个变量必须先定义后引用.所谓变量存在是指系统为这个变量分配一块存储空间,此时对变量的操作,就是对变量所对应的存储空间中存放的数据进行操作.人们将变量占据 ...
- 递推DP UVA 607 Scheduling Lectures
题目传送门 题意:教授给学生上课,有n个主题,每个主题有ti时间,上课有两个限制:1. 每个主题只能在一节课内讲完,不能分开在多节课:2. 必须按主题顺序讲,不能打乱.一节课L时间,如果提前下课了,按 ...
- 构造 Codeforces Round #310 (Div. 2) B. Case of Fake Numbers
题目传送门 /* 题意:n个数字转盘,刚开始每个转盘指向一个数字(0~n-1,逆时针排序),然后每一次转动,奇数的+1,偶数的-1,问多少次使第i个数字转盘指向i-1 构造:先求出使第1个指向0要多少 ...
- 题解报告:hdu 2057 A + B Again
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2057 问题描述 我们的HDOJ必须有许多A + B问题,现在又有新的问题出现. 给你两个十六进制整数, ...