zoukankan      html  css  js  c++  java
  • 面向对象之 组合 封装 多态 property 装饰器

    1.组合

    什么是组合?

        一个对象的属性是来自另一个类的对象,称之为组合

    为什么要用组合

      组合也是用来解决类与类代码冗余的问题

    3.如何用组合

    # obj1.xxx=obj2
    '''
    '''
    # 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 OldboyPeople:
    # school = 'Oldboy'
    # def __init__(self, name, age, gender):
    # self.name = name
    # self.age = age
    # self.gender = gender
    #
    # class OldboyStudent(OldboyPeople):
    # def choose_course(self):
    # print('%s is choosing course' %self.name)
    #
    # class OldboyTeacher(OldboyPeople):
    # def __init__(self, name, age, gender,level,salary):
    # super(OldboyTeacher, self).__init__(name, age, gender)
    # # OldboyPeople.__init__(self, name, age, gender)
    # self.level=level
    # self.salary=salary
    # def score(self,stu,num):
    # 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.choose_course()
    #
    # stu1.courses=[]
    # stu1.courses.append(python_obj)
    # stu1.courses.append(linux_obj)
    # stu1.courses[0].tell_course()
    #
    #
    # tea2=OldboyTeacher('kevin',38,'male',5,3000)
    # tea2.score(stu1,60)

    '''
    封装
    什么是封装?
    封装指的是把属性装进一个容器
    封 指的是将容器内的属性隐藏你起来,但是这种隐藏是对外不对内的

    为何要封装?
    封装不是单纯意义的隐藏
    封装数据属性的目的:将数据属性封装起来,类外部的使用就无法直接操作改属性了
    需要类内部开一个接口给使用者,类的设计者可以再接口之上附加任意逻辑,从而严格控制使用者对属性的操作

    封装函数(功能)属性的目的:隔离复杂度,(很多功能是给内部用的,给外部封装起来隔离复杂度)

    3.如何封装?
      只需要在属性钱加上__开头,该属性就会被隐藏起来,该隐藏具备的特点:
      1.只是一种语法意义上的变形,即__开头的属性会在检测语法时发生变形,_类名__属性名
      2.这种隐藏式对外不对内的,因为在类内部检测语法时所有的代码都发生了变形
      3.这种变形只在检测语法时发生一次,在类定义之后新增的__开头的属性并不会发生变形
      4.如果父类不想让子类覆盖自己的属性,可以再属性前加__开头


    # class Foo:
    # __x=111 #_Foo__x
    # def __init__(self,m,n):
    # self.__m=m # self._Foo__m=m
    # self.n=n
    #
    # def __func(self): #_Foo__func
    # print('Foo.func')
    #
    # def func1(self):
    # print(self.__m) #self._Foo__m
    # print(self.__x) #self._Foo__x

    # print(Foo.__dict__)
    # Foo.__x
    # Foo.__func
    # print(Foo._Foo__x)
    # print(Foo._Foo__func)


    obj=Foo(10,20)
    # print(obj.__dict__)
    # print(obj.n)
    # print(obj.__m)
    # print(obj._Foo__m)

    # obj.func1()
    # obj._Foo__func()

    # obj.__yyy=3333 #特点三,
    # print(obj.__dict__)
    # print(obj.__yyy)

    # Foo.__zzz=444
    # Foo.zzz=333
    # print(Foo.__dict__)
    # print(Foo.__zzz)



    # class Foo:
    # def __f1(self): #_Foo__f1
    # print('Foo.f1')
    #
    # def f2(self):
    # print('Foo.f2')
    # self.__f1() #self._Foo__f1
    #
    # class Bar(Foo):
    # def __f1(self): #_Bar__f1
    # print('Bar.f1')
    #
    # obj=Bar()
    # obj.f2()


    # 封装数据属性的真实意图
    # 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,new_name,new_age):
    # if type(new_name) is not str:
    # print('name error')
    # return
    # self.__name=new_name
    # if type(new_age) is not int:
    # print('age error')
    # return
    # self.__age=new_age
    # def clear_info(self):
    # del self.__name
    # del self.__age
    #
    # obj1=People('aaa',10)
    # obj1.tell_info()
    # obj1.set_info('aaa',111)
    # print(obj1.__dict__)
    # obj1.clear_info()
    # print(obj1.__dict__)


    # 封装函数属性的真实意图
    # 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装饰器:将类中定义的函数(功能)伪装成数据属性
    # @property #查看属性的功能
    # @xxx.setter #修改属性的功能
    # @xxx.deleter #删除属性的功能
    # name=property(xxx_name,yyy_name,zzz_name) #古老的做法非装饰下使用这种,(按照括号里的参数名顺序)
    '''
    例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)

    成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
      体质指数(BMI)=体重(kg)÷身高^2(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):
    # print(self.weight/(self.height**2))
    #
    # obj1=People('aaa',65,1.78)
    # obj1.bmi
    # obj1.height=1.70
    # # obj1.bmi()
    # obj1.bmi


    # 需要了解的property的用法 setter,deleter
    # 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('name error')
    # 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)
    #
    # del obj.name
    # print(obj.__dict__)

    # 常规工作常使用套路
    # class People:
    # def __init__(self,name):
    # self.__name=name
    # def xxx_name(self):
    # return '<name:%s>' %self.__name
    #
    # def yyy_name(self,new_name):
    # if type(new_name) is not str:
    # print('名字必须是str类型')
    # return
    # self.__name=new_name
    # def zzz_name(self):
    # del self.__name
    #
    # name=property(xxx_name,yyy_name,zzz_name)
    #
    # obj=People('egon')
    # print(obj.name)
    #
    # obj.name=123
    # print(obj.name)
    #
    # del obj.name
    # print(obj.__dict__)
    '''


    多态
    1.什么是多态
    同一事物的多种形态
    在程序中继承可以表现出多态
    2.为何要用多态?
    多态性:可以再不用考虑对象具体类型(类)的前提下而直接使用对象下的方法
    多态的精髓:统一标准
    3如何使用多态?
    # python崇尚鸭子类型
    '''
    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)



    # python崇尚鸭子类型
    # class Memory:
    # def read(self):
    # print('mem read')
    #
    # def write(self):
    # print('mem write')
    #
    # class Disk:
    # def read(self):
    # print('disk read')
    #
    # def write(self):
    # print('disk write')
    #
    # class Cpu:
    # def read(self):
    # print('cpu read')
    #
    # def write(self):
    # print('cpu write')
    #
    #
    # obj1=Memory()
    # obj2=Disk()
    # obj3=Cpu()
    #
    # obj1.read()
    # obj2.read()
    # obj3.read()
    #
    #
    # ''.__len__()
    # [].__len__()
    # len([1,2,3]) #[1,2,3].__len__()
    '''


  • 相关阅读:
    ajax异步服务器获取时间
    JavaScript基本知识
    JavaScript使用button提交表单
    spring与hibernate整合
    Spring的事务属性
    注解方式实现Spring声明式事务管理
    svn的安装使用
    sbn
    恢复oracle中误删除drop掉的表
    ORA-20000: ORU-10027: buffer overflow, limit of 2000 bytes的解决办法
  • 原文地址:https://www.cnblogs.com/frank007/p/9877790.html
Copyright © 2011-2022 走看看