组合
什么是组合
组合指的是某一个对象拥有一个属性,该属性的值是另外一个类的对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Foo: pass class Bar: pass obj=Foo() obj.attr=Bar() obj.xxx obj.attr.yyy
为何要用组合
通过为某一个对象添加属性(属性的值是另外一个类的对象)的方式,可以间接地将两个类关联到一起,从而类与类之间的代码冗余
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
如何用组合
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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) # print(stu1.courses) stu1.tell_all_course() tea1=OldboyTeacher('egon',18,'male',10) tea1.courses.append(python) # print(tea1.courses) tea1.tell_all_course()
多态
什么是多态
多态指的是同一种/类事物的不同形态
为何要用多态
多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象
多态性的精髓:统一
如何使用多态
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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()
# Animal() # 父类只是用来建立规范的,不能用来实例化的,更无需实现内部的方法
封装
什么是封装
装:往容器里/名称空间里存入名字
封:代表将存放于名称空间中的名字给藏起来,这种隐藏对外不对内
为何要用封装
封数据属性
封函数类型
如何封装
在类内定义的属性前加__开头(没有__结果)
总结:
1.__开头的属性实现的隐藏仅仅只是一种语法意义上的变形,并不会真的限制类外部的访问
2.该变形操作只在类定义阶段检测语法时发生一次,类定义阶段之后新增的__开头的属性并不会变形
3.如果父类不想让子类覆盖自己的属性,可以在属性前加__开头
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Foo(): __x=111 def __init__(self,name,age): self.__name=name self.__age=age def tell_info(self): print(self.__name,self.__age) def set_info(self,name,age): self.__name=name self.__age=age obj=Foo('lgh',20) obj.set_info('LGH',18) obj.tell_info()
property装饰器是用来将类内的函数属性伪装成数据属性
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class People: def __init__(self,name,weight,hight): self.__name=name self.__weight=weight self.__hight=hight @property def bmi(self): return self.__weight/(self.__hight**2) obj=People('lgh',60,1.75) print(obj.bmi)