(继承补充)组合
obj=fun()#对象
obj.attr=foo()#对象的属性等于另一个对象
什么是组合:
A类的对象具备某一个属性,该属性的值是B类的对象
基于这种方式就把A类与B类组合到一起
对象既能使用A类中的数据与功能,也能使用B类中的数据与功能
为什么要用组合:
组合与继承的作用一样,都是用来减少类与类之间的重复代码
#组合不属于继承
#类使用将变量及处理其的函数捆绑起来
#继承是强耦合,组合是解耦合
如何用组合:
class People:
def __init__(self,name,age):
self.name=name
self.age=age
self.eat=[]
def tell_eat(self):
for i in self.eat:
i.tell_info()
class Eat:
def __init__(self,e_name,e_price):
self.e_name=e_name
self.e_price=e_price
def tell_info(self):
print('食物%s 价格%s'%(self.e_name,self.e_price))
obj=fun()#对象
obj.attr=foo()#对象的属性等于另一个对象
什么是组合:
A类的对象具备某一个属性,该属性的值是B类的对象
基于这种方式就把A类与B类组合到一起
对象既能使用A类中的数据与功能,也能使用B类中的数据与功能
为什么要用组合:
组合与继承的作用一样,都是用来减少类与类之间的重复代码
#组合不属于继承
#类使用将变量及处理其的函数捆绑起来
#继承是强耦合,组合是解耦合
如何用组合:
class People:
def __init__(self,name,age):
self.name=name
self.age=age
self.eat=[]
def tell_eat(self):
for i in self.eat:
i.tell_info()
class Eat:
def __init__(self,e_name,e_price):
self.e_name=e_name
self.e_price=e_price
def tell_info(self):
print('食物%s 价格%s'%(self.e_name,self.e_price))
p=People('张三',18)
eat1=Eat('肯德鸡',38)
eat2=Eat('烤乳猪',120)
p.eat.append(eat)
多态与多态性
什么是多态:
同一种事物有多种形态在程序中用继承可以表现出多态
多态性:
在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象
多态性的精髓:统一
import abc
class Animal(metaclass=abc.ABCMeta):#强制子类使用这套标准中加@..的名字,子类没有报错
@abc.abstractmethod #被强制的名字
def speak(self):
pass
def run(self):
pass
# Animal() # 父类只是用来建立规范的,不能用来实例化的,更无需实现内部的方法
eat1=Eat('肯德鸡',38)
eat2=Eat('烤乳猪',120)
p.eat.append(eat)
多态与多态性
什么是多态:
同一种事物有多种形态在程序中用继承可以表现出多态
多态性:
在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象
多态性的精髓:统一
import abc
class Animal(metaclass=abc.ABCMeta):#强制子类使用这套标准中加@..的名字,子类没有报错
@abc.abstractmethod #被强制的名字
def speak(self):
pass
def run(self):
pass
# Animal() # 父类只是用来建立规范的,不能用来实例化的,更无需实现内部的方法
class People(Animal):
def speak(self):
print('say hello')
def speak(self):
print('say hello')
class Dog(Animal):
def speak(self):
print('汪汪汪')
def run(self):
pass
python推崇鸭子类型:(像什么,就有什么的特征)
class Txt:
def read(self):
pass
class Disk:
def read(self):
pass
#BMI=体重(kg)÷身高^2(m)
#首先需要明确。bmi是算出来的,不是一个固定死的值,很明显人的bmi值听起来更像一个名词而非动词,于是我们需要为bmi这个函数添加装饰器将其伪装成一个数据属性
# @property装饰器是用来将类内的函数属性伪装成数据属性
#@property装饰的函数可以调setter及deleter
# 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('不让删')
# del self.__name
#
# obj=People('egon')
#
# # print(obj.name)
# # obj.name='EGON'
# # obj.name=123
# # print(obj.name)
#
# del obj.name
# print(obj.__dict__)
def speak(self):
print('汪汪汪')
def run(self):
pass
python推崇鸭子类型:(像什么,就有什么的特征)
class Txt:
def read(self):
pass
class Disk:
def read(self):
pass
#BMI=体重(kg)÷身高^2(m)
#首先需要明确。bmi是算出来的,不是一个固定死的值,很明显人的bmi值听起来更像一个名词而非动词,于是我们需要为bmi这个函数添加装饰器将其伪装成一个数据属性
# @property装饰器是用来将类内的函数属性伪装成数据属性
#@property装饰的函数可以调setter及deleter
# 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('不让删')
# del self.__name
#
# obj=People('egon')
#
# # print(obj.name)
# # obj.name='EGON'
# # obj.name=123
# # print(obj.name)
#
# del obj.name
# print(obj.__dict__)
封装
self.__name=name #_类名__name 定义阶段转形
什么是封装?
装:往容器/名称空间里存入名字
封:代表将存放于名称空间中的名字给藏起来,这种隐藏对外不对内
self.__name=name #_类名__name 定义阶段转形
什么是封装?
装:往容器/名称空间里存入名字
封:代表将存放于名称空间中的名字给藏起来,这种隐藏对外不对内
补充说明:封装绝对不是单纯意义的隐藏
需知定义属性的目的就是为了让使用者去用,使用者要想使用类内部隐藏的属性
需要类的设计者在类内部开一个接口(定义一个方法),在该方法内访问隐藏的属性
,使用者以后就通过该方法来“间接地”访问内部隐藏的属性
作为类的设计者可以在接口之上附加任意逻辑从而严格控制类的使用者对属性的操作
如何封装?
1. __开头的属性实现的隐藏仅仅只是一种语法意义上的变形,并不会真的限制类外部的访问
2. 该变形操作只在类定义阶段检测语法时发生一次,类定义阶段之后新增的__开头的属性并不会变形
3. 如果父类不想让子类覆盖自己的属性,可以在属性前加__开头
封装形式?
封装数据属性:把数据属性封装起来,然后需要开辟接口给类外部的使用者使用,好处是我们可以在接口之上添加控制逻辑,从而严格空间访问者对属性的操作
class People:
def __init__(self,name):
self.__name=name
需知定义属性的目的就是为了让使用者去用,使用者要想使用类内部隐藏的属性
需要类的设计者在类内部开一个接口(定义一个方法),在该方法内访问隐藏的属性
,使用者以后就通过该方法来“间接地”访问内部隐藏的属性
作为类的设计者可以在接口之上附加任意逻辑从而严格控制类的使用者对属性的操作
如何封装?
1. __开头的属性实现的隐藏仅仅只是一种语法意义上的变形,并不会真的限制类外部的访问
2. 该变形操作只在类定义阶段检测语法时发生一次,类定义阶段之后新增的__开头的属性并不会变形
3. 如果父类不想让子类覆盖自己的属性,可以在属性前加__开头
封装形式?
封装数据属性:把数据属性封装起来,然后需要开辟接口给类外部的使用者使用,好处是我们可以在接口之上添加控制逻辑,从而严格空间访问者对属性的操作
class People:
def __init__(self,name):
self.__name=name
def tell_name(self):
# 添加逻辑
return self.__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('取款')
# 添加逻辑
return self.__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()
封装的终极奥义:明确地区分内外,对外是隐藏的,对内是开放的
self.__card()
self.__auth()
self.__input()
self.__print_bill()
self.__take_money()
封装的终极奥义:明确地区分内外,对外是隐藏的,对内是开放的