zoukankan      html  css  js  c++  java
  • 13 Apr 18 组合 封装

    13 Apr 18
    一、组合
    解决类与类之间代码冗余问题有两种解决方案:1、继承 2、组合
    1、继承:描述的是类与类之间,什么是什么的关系
    2、组合:描述的是类与类之间的关系,是一种什么有什么关系;一个类产生的对象,该对象拥有一个属性,这个属性的值是来自于另外一个类的对象
    #组合不属于继承
    #类的使用将变量及处理其的函数捆绑起来
    #继承是强耦合,组合是解耦合
     
    class Date:
        def __init__(self,year,mon,day):
            self.year = year
            self.mon = mon
            self.day = day
        def tell_birth(self):
            print('出生年月日<%s-%s-%s>' % (self.year, self.mon, self.day))
     
    class OldboyPeople:
        school = 'oldboy'
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
     
    class OldboyTeacher(OldboyPeople):
        def __init__(self,name,age,sex,level,salary):
            super().__init__(name,age,sex)
            self.level=level
            self.salary=salary
        def change_score(self):
            print('teacher %s is changing score' %self.name)
     
    class Oldboystudent(OldboyPeople):
        def __init__(self,name,age,sex,course,):
            super().__init__(name,age,sex,)
            self.course=course
        def choose(self):
            print('student %s choose course' %self.name)
     
    stu1=Oldboystudent('张三',16,'male','linux')
    stu1.birth=Date(2002,3,3)
    stu1.birth.tell_birth()
     
    二、组合练习
    class OldboyPeople:
        school = 'oldboy'
        def __init__(self, name, age, sex,):
            self.name = name
            self.age = age
            self.sex = sex
     
    class OldboyTeacher(OldboyPeople):
        def __init__(self,name,age,sex,level,salary):
            super().__init__(name,age,sex)
            self.level=level
            self.salary=salary
            self.courses=[]
     
        def change_score(self):
            print('teacher %s is changing score' %self.name)
     
        def tell_course_info(self):
            print(('老师%s 教授的课程信息如下' %self.name).center(50,'='))
            for course_obj in self.courses:
                course_obj.info()
     
    class Oldboystudent(OldboyPeople):
        def __init__(self,name,age,sex):
            super().__init__(name,age,sex,)
            self.courses=[]
        def choose(self):
            print('student %s choose course' %self.name)
        def tell_course_info(self):
            print(('学生%s 学习的课程信息如下' % self.name).center(50, '='))
            for course_obj in self.courses:
                course_obj.info()
     
    class Course:
        def __init__(self,cname,period,price):
            self.cname=cname
            self.period=period
            self.price=price
        def info(self):
            print('课程信息<名字:%s 周期:%s  价钱:%s>' %(self.cname,self.period,self.price))
     
    tea1=OldboyTeacher('egon',18,'male',9,3.1)
    stu1=Oldboystudent('张三',16,'male')
     
    python=Course('Python全栈开发','5mons',3000)
    linux=Course('Linux高级架构师','5mons',2000)
    go=Course('Go开发工程师','3mons',1000)
     
    # 给老师添加课程
    tea1.courses.append(python)
    tea1.courses.append(linux)
    print(tea1.courses)
    tea1.courses[0].info()
    for course_obj in tea1.courses:
        course_obj.info()
    tea1.tell_course_info()
     
    # 给学生添加课程
    stu1.courses.append(python)
    stu1.courses.append(go)
    stu1.courses.append(linux)
    stu1.tell_course_info()
     
    三、如何封装以及封装的目的
    1、什么是封装:
    装就是把一堆属性存起来,封的概念就把这些属性给隐藏起来
    强调:封装单从字面意思去看等同于隐藏,但其实封装绝对不是单纯意义的隐藏
     
    2、如何用封装
    如何把属性隐藏起来,就在属性前面加上__开头(注意不要加__结尾)
    注意:
    a、其实这种隐藏只是一种语法上的变形,对外不对内
    为一个属性名加__开头(注意不要加__结尾),会在类定义阶段将属性名统一变形:_自己的类名__属性名
     
    class Foo:
        __x=1111 #_Foo__x=1111
        def __init__(self,y):
            self.__y=y #self._Foo__y=y
        def __f1(self): #_Foo__f1
            print('Foo.f1')
        def get_y(self):
            print(self.__y) # print(self._Foo__y)
     
    obj=Foo(22222)
    print(obj.x)
    print(obj.__x)
    obj.__f1()
    print(obj.y)
    print(obj.__y)
    print(Foo.__dict__)
    print(obj._Foo__x)
    print(obj._Foo__y)
    obj._Foo__f1()
    obj.get_y()
     
    b、这种语法意义上变形,只在类定义阶段发生一次,类定义之后,新增的__开头的属性都没有变形的效果
     
    Foo.__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1
    print(Foo.__dict__)
     
    obj.__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb=2
    print(obj.__dict__)
     
    c、如果父类不想让子类覆盖自己的方法,可以在方法名前加__开头
    class Foo:
        def __f1(self): #_Foo__f1
            print('Foo.f1')
        def f2(self):
            print('Foo.f2')
            self.__f1() #obj._Foo__f1()
    class Bar(Foo):
        def __f1(self): #_Bar__f1
            print("Bar.f1")
     
    obj=Bar()
    obj.f2()
     
    3、为什么要用封装
    a、封装数据属性的目的:把数据属性封装起来,然后需要开辟接口给类外部的使用者使用,好处是我们可以在接口之上添加控制逻辑,从而严格空间访问者对属性的操作
    class People:
        def __init__(self,name,age):
            self.__name=name
            self.__age=age
        def tell_info(self):
            u=input('user>>: ').strip()
            p=input('pwd>>: ').strip()
            if u == 'egon' and p == '123':
                print(self.__name,self.__age)
        def set_info(self,name,age):
            if type(name) is not str:
                raise TypeError('用户名必须为str类型')
            if type(age) is not int:
                raise TypeError('年龄必须为int类型')
            self.__name=name
            self.__age=age
     
    p=People('egon',18)
    p.tell_info()
    p.tell_info()
    p.set_info('EGON',19)
    p.tell_info()
    p.set_info(353535353535353535,20)
    p.set_info('EGON','20')
     
    b、封装函数属性的目的:为了隔离复杂度
     
    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()
     
    obj=ATM()
    obj.withdraw()s
     
    c、封装的终极奥义:明确地区分内外,对外是隐藏的,对内是开放的
  • 相关阅读:
    编程谜题:提升你解决问题的训练场
    同态加密实现数据隐私计算,能让你的小秘密更加秘密
    interviewstreet pair
    x & (x 1)==0
    uva 11991 Easy Problem from Rujia Liu?
    hdoj 1230 火星A+B
    hdoj 1711 KMP Number Sequence
    HackerRank网站,为编码程序员们提供一个以编码谜题和现实生活中遇到的编码难题为基础的新兴的社交平台
    ACM博弈知识汇总
    hdoj 1202 水水更健康
  • 原文地址:https://www.cnblogs.com/zhangyaqian/p/py20180413.html
Copyright © 2011-2022 走看看