组合 封装 多态

一.组合

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)
原文地址:https://www.cnblogs.com/gongcheng-/p/9845919.html