一.组合
1.什么是组合
一个对象的属性是来自另一外一个类的对象,称之为组合
2.为何用组合
组合也是用来解决类与代码冗余的问题
3.如何用组合
class Foo: aaa=1111 def __init__(self,x,y) self.x=x self.y=y def func1(self): print('Foo内的功能') class Bar: bbb=2222 def __init__(self,m,n): self.m = m self.n = n def func2(self): print('Bar内的功能') obj1=Foo(10,20) obj2=Bar(30,40) obj1.xxx=obj2 print(obj1.x,obj1.y,obj1.aaa,obj1.func1) print(obj1.xxx.m,obj1.xxx.n,obj1.xxx.bbb,obj1.xxx.func2)
组合另一个类中的多个对象
class OldboyPeple: school = 'Oldboy' def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender class OldboyStudent(OldboyPleople): def choose_course(self): print('%s is choosing course'%self.name) class OldboyTeacher(OldboyPeople): def choose_course(self): stu,num=num print('老师%s给学生%s打分%s'%(self.name,stu.name,num)) class Course: def __init__(self,course_name,course_price,course_period): self.course_name = course_name self.course_price=course_price self.course_period=course_period def tell_course(self): print('课程名:<%s>价格:[%s] 周期:[%s]%(self.course_name,self.course_price,self.course_period)) python_obj = Course('python开发',3000,'5mons') linux_obj=Course('linux运维',5000,'3mons') stu1=OldboyStudent('egon',18,'male') stu1.course=[] stu1.courses.append(linux_obj)
stu1.courses.append(python)obj)
stu1.courses[0].tell_course()
二.封装
1.什么是封装
装指的是吧属性装进一个容器
封指的是隐藏的意思,但是这种隐藏式对外不内的
2.为何要封装
封装不是单纯意义的隐藏
封装数据属性的目的:将数据属性封装起来,类外的使用就无法直接操作该数据属性了
需要内部开一个接口给使用者,类的实际者可以在接口上附带任何逻辑,从而严格
控制使用者对属性的操作
封装函数属性的目的:隔离复杂度
3.如何封装
只要在属性前加上__开头,该属性就会被隐藏起来,该隐藏具备的特点:
1.只要一种语法意义上的变形,即__开头的属性会在检测语法时发生变形,_类名__属性名.
2.这种隐藏是对外不对内的,因为在类内部检测语法时所有的代码统一都会发生变形
3.这种变形值在检测时发生一次,在类定义之后新增的__开头的属性并不会发生变形
4.如果父类不想让子类覆盖自己的属性,可以在属性前加__开头.
#其实这仅仅这是一种变形操作且仅仅只在类定义阶段发生变形 #类中所有双下划线开头的名称如__x都会在类定义时自动变形成:_类名__x的形式: class A: __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N def __init__(self): self.__X=10 #变形为self._A__X def __foo(self): #变形为_A__foo print('from A') def bar(self): self.__foo() #只有在类内部才可以通过__foo的形式访问到. #A._A__N是可以访问到的, #这种,在外部是无法通过__x这个名字访问到。
内部调用
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.__card(self) a.withdraw()
隐藏的属性可以被内部使用
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.__card(self) a.withdraw()
三.property装饰器.
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
即:可以把函数结果作为属性被返回.
例一:BMI指数(bmi是计算而来,但很明显它听起来是一个属性而非方法,如果我们将其做成一个属性,更便于理解)
成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖:高于32
体质指数(BMI)=体重(kg)➗身高²(m)
EX:70kg ➗(1.75✖️1.75) = 22.86
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',70,1.82) obj.height=1.85 print(obj.bmi)
property的需要了解的用法
class People: def __init__(self,name) self.__name=name @property def name(self) return'<name:%s>self.name @name.setter def name(self,new_name): if type(new_name)is not str: print('名字必须是str类型") return self.__name=new_name @name.deleter def name(self) del self.name obj=People('egon') print(obj.name) obj.name=123 print(obj.name) def obj.name print(obj.__dict__)
四.多态,
1.什么是多态
同一事物的多种形态
2.为何要用多态
多态性:指
import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def speak(self): pass # Animal() # 父类不能实例化,因为父类本身就是用来制定标准的 class People(Animal): def speak(self): print('say hello') # def jiao(self): # print('say hello') class Dog(Animal): def speak(self): print('汪汪汪') class Pig(Animal): def speak(self): print('哼哼哼') peo=People() dog1=Dog() pig1=Pig() # # peo.speak() dog1.speak() pig1.speak() def speak(animal): animal.speak() speak(peo) speak(dog1) speak(pig1)