组 合
组合:
某一个对象的拥有属性,该属性等于另一个类对象
用组合的目的:
通过为某一个对象增加属性,可以间接的把两个类 组合/关联到一起
其次减少类与类之间代码冗余
组合列子:
class Oldboypeople: school = 'oldboy' def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex class Student(Oldboypeople): def __init__(self,name,age,sex,score=0): Oldboypeople.__init__(self,name,age,sex) self.score = score self.course = [] def course(self): print('%s course' %self.name) def tell_all_course(self): print('学生[%s] 的课程如下:') for object in self.course: object.tell_info() class Teacher(Oldboypeople): def __init__(self,name,age,sex,level): Oldboypeople.__init__(self,name,age,sex,) self.level = level self.course = [] def score(self,stu,num): stu.score = num def tell_all_course(self): print('[%s] 老师教授的课程如下:' %self.name) for object in self.course: object.tell_info() class Course: def __init__(self,b_name,b_price,b_period): self.b_name = b_name self.b_price = b_price self.b_period = b_period def tell_info(self): print('书名:%s,价格:%s,周期:%s' %(self.b_name,self.b_price,self.b_period)) python = Course('python 全栈开发',22000,3) linux = Course('linux 高级架构',22000,2) stu = Student('wxx',18,'male') teach = Teacher('刘xx',18,'male',10) stu.course.append(python) stu.course.append(linux) stu.tell_all_course() teach.course.append(python) teach.course.append(linux) teach.tell_all_course()
多态与多态性
多 态: 指同种事物的不同形态
多态性: 在多态的背景下,可以不用考虑对象具体类型下而直接使用对象
多态的精髓在于:统一规范
多态统一规范有两种类型:
第一种:父类用来强制规范,不能实例化。
装饰器 @abc.abstractmethod
下面为父类的例子:
import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def speak(self): pass @abc.abstractmethod def run(self): pass
第二种:鸭子类型(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()
封 装
封 装:
装:指往名称空间里存名字
封:将名称空间里的名字隐藏起来,对外隐藏,对内不隐藏
封装简单用法:
在要封装的属性前加 __ 双下划线
代码示例:
class auth: __x = 11 def __init__ (self,name,age,sex) self.__name = name self.__age = age self.__sex = sex def get_info(self): print(self.__name,self.__age,self.__x) # print(self._Foo__name,self._Foo__age,self._Foo__x)
封装数据属性:
外部无法访问数据属性,可以在类里面设置接口,间接的操作属性,可以在接口里设置任意的逻辑,达到严格控制属性的要求
代码示例:
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','18') 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()
装饰器:
property:(函数属性变成数据属性)
用来将类函数属性伪装成数据属性 # 被装饰以后,调函数时不用加括号
代码示例:
class People: def __init__(self,name,weight,height): self.name=name self.weight=weight self.height=height @property def bmi(self): return self.weight / (self.height ** 2) obj=People('egon',80,1.83) obj.height=1.85 obj.weight=75 #print(obj.bmi()) print(obj.bmi)
classmethod:(绑定类名)
默认将类名传给函数属性(对象来调用也传的是类名)
另外一种类的实例化
代码示例
class people: @classmethod def from_conf(cls): return cls(settings.IP, settings.PORT)
staticmethod: (非绑定方法)
既不绑定对象,也不绑定类名
代码示例
import settings class MySql: def __init__(self, ip, port): self.id = self.create_id() self.ip = ip self.port = port def tell_info(self): print('<id:%s ip:%s port:%s>' % (self.id, self.ip, self.port)) @classmethod def from_conf(cls): return cls(settings.IP, settings.PORT) @staticmethod def create_id(): import uuid return uuid.uuid4()