zoukankan      html  css  js  c++  java
  • day28-python-封装

    内容回顾

    上节课复习:
        1、编程范式/思想
            面向过程
                介绍:
                    核心是"过程"二字
                    过程就是"流水线"
                    过程终极奥义是将程序流程化
    
    
                优点:
                    1、将程序流程化,进而程序的设计会变得简单化
    
                缺点:
                    1、可扩展性差
    
            面向对象
                 介绍:
                    核心是"对象"二字
                    对象就是"容器",用来盛放数据与功能
                    对象终极奥义是将程序进行高度整合
    
                优点:
                    1、提升程序的解耦合程度,进而增强程序的可扩展性
    
                缺点:
                    1、设计复杂
    
        2、面向对象编程
            一:现实生活中:
                1、先找出现实生活中的对象
                2、然后总结归纳出现实生活中的类
    
            二:程序中:
            1、先定义程序中的类
            2、后调用类产生程序中对象(调用类的过程又称之为实例化)
    
    class Student:
        school = 'Oldboy'
    
        # 该方法会在对象产生之后自动执行,专门为对象进行初始化操作,可以有任意代码,但一定不能返回非None的值
    
        def __init__(self, name, sex, age):
            self.name = name
            self.sex = sex
            self.age = age
    
        def choose(self):
            print('%s is choosing a course' % self.name)
    
    
    stu1 = Student('李建刚', '男', 28)
    stu2 = Student('王大力', '女', 18)
    
    1、类中的数据属性
    print(id(Student.school))
    print(id(stu1.school))
    print(id(stu2.school))
    
    Student.school = 1111111
    stu1.school = 1111111
    print(stu1.school)
    print(stu2.school)
    
    2、类中的函数属性
    print(Student.choose)
    Student.choose(stu1)  # 类可以用,但就是一个普通函数
    stu1.choose()
    stu2.choose()
    
    print(Student.__dict__)
    print(stu1.__dict__)
    print(stu2.__dict__)
    
    Student.xxx = 1
    print(Student.xxx)
    stu1.age = 20
    stu1.yyy = 30
    
    print(stu1.xxx)
    stu1.xxx = 3333333333
    print(stu1.__dict__)
    print(stu1.xxx)
    print(stu2.xxx)
    
    l = []  # l=list([])
    print(type(l))
    
    print(type(stu1))
    
    

    封装

    # 一:封装介绍
    # 封装是面向对象三大特性最核心的一个特性
    # 封装 < ->整合
    
    
    # 二、将封装的属性进行隐藏操作
    # 1、如何隐藏:在属性名前加__前缀, 就会实现一个对外隐藏属性效果
    该隐藏需要注意的问题:
    # I: 在类外部无法直接访问双下滑线开头的属性,但知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如Foo._A__N,
    # 所以说这种操作并没有严格意义上地限制外部访问,仅仅只是一种语法意义上的变形。
    
    
    class Foo:
        __x = 1  # _Foo__x
    
        def __f1(self):  # _Foo__f1
            print('from test')
    
    
    # print(Foo.__dict__)
    # print(Foo._Foo__x)
    # print(Foo._Foo__f1)
    
    # II:这种隐藏对外不对内, 因为__开头的属性会在检查类体代码语法时统一发生变形
    
    
    class Foo:
        __x = 1  # _Foo__x = 1
    
        def __f1(self):  # _Foo__f1
            print('from test')
    
        def f2(self):
            print(self.__x)  # print(self._Foo__x)
            print(self.__f1)  # print(self._Foo__f1)
    
    
    print(Foo.__x)
    print(Foo.__f1)
    obj = Foo()
    obj.f2()
    
    # III: 这种变形操作只在检查类体语法的时候发生一次,之后定义的__开头的属性都不会变形
    
    
    class Foo:
        __x = 1  # _Foo__x = 1
    
        def __f1(self):  # _Foo__f1
            print('from test')
    
        def f2(self):
            print(self.__x)  # print(self._Foo__x)
            print(self.__f1)  # print(self._Foo__f1)
    
    
    Foo.__y = 3
    print(Foo.__dict__)
    print(Foo.__y)
    
    
    class Foo:
        __x = 1  # _Foo__x = 1
    
        def __init__(self, name, age):
            self.__name = name
            self.__age = age
    
    
    obj = Foo('egon', 18)
    print(obj.__dict__)
    print(obj.name, obj.age)
    
    # 2、为何要隐藏?
    # I、隐藏数据属性"将数据隐藏起来就限制了类外部对数据的直接操作,然后类内应该提供相应的接口来允许类外部间接地操作数据,接口之上可以附加额外的逻辑来对数据的操作进行严格地控制:
    # 设计者:egon
    
    
    class People:
        def __init__(self, name):
            self.__name = name
    
        def get_name(self):
            # 通过该接口就可以间接地访问到名字属性
            # print('小垃圾,不让看')
            print(self.__name)
    
        def set_name(self, val):
            if type(val) is not str:
                print('小垃圾,必须传字符串类型')
                return
            self.__name = val
    
    
    # 使用者:王鹏
    obj = People('egon')
    print(obj.name)  # 无法直接用名字属性
    obj.set_name('EGON')
    obj.set_name(123123123)
    obj.get_name()
    # II、隐藏函数/方法属性:目的的是为了隔离复杂度
    
    

    作业

    # 整合->解耦合->扩展性增强
    
    class School:
        school_name = 'OLDBOY'
    
        def __init__(self, nickname, addr):
            self.nickname = nickname
            self.addr = addr
            self.classes = []
    
        def related_class(self, class_obj):
            # self.classes.append(班级名字)
            # self.classes.append(class_name)
            self.classes.append(class_obj)
    
        def tell_class(self):  # 改
            # 打印的班级的名字
            print(self.nickname.center(60, '='))
            # 打印班级开设的课程信息
            for class_obj in self.classes:
                class_obj.tell_course()
    
    
    # # 一:学校
    # #1、创建校区
    school_obj1 = School('老男孩魔都校区', '上海')
    school_obj2 = School('老男孩帝都校区', '北京')
    
    # 2、为学校开设班级
    # 上海校区开了:脱产14期,上海校区开了脱产15期
    school_obj1.related_class("脱产14期")
    school_obj1.related_class("脱产15期")
    
    # 北京校区开了:脱产29期
    school_obj2.related_class("脱产29期")
    
    # 3、查看每个校区开设的班级
    school_obj1.tell_class()
    school_obj2.tell_class()
    
    
    class Class:
        def __init__(self, name):
            self.name = name
            self.course = None
    
        def related_course(self, course_obj):
            # self.course = course_name
            self.course = course_obj
    
        def tell_course(self):
            print('%s' % self.name, end=" ")
            self.course.tell_info()  # 打印课程的详细信息
    
    
    # 二:班级
    # 1、创建班级
    class_obj1 = Class('脱产14期')
    class_obj2 = Class('脱产15期')
    class_obj3 = Class('脱产29期')
    
    # 2、为班级关联一个课程
    class_obj1.related_course('python全栈开发')
    class_obj2.related_course('linux运维')
    class_obj3.related_course('python全栈开发')
    
    # 3、查看班级开设的课程信息
    class_obj1.tell_course()
    class_obj2.tell_course()
    class_obj3.tell_course()
    
    # 4、为学校开设班级
    # 上海校区开了:脱产14期,上海校区开了脱产15期
    school_obj1.related_class(class_obj1)
    school_obj1.related_class(class_obj2)
    
    # 北京校区开了:脱产29期
    school_obj2.related_class(class_obj3)
    
    
    school_obj1.tell_class()
    school_obj2.tell_class()
    
    
    class Course:
        def __init__(self, name, period, price):
            self.name = name
            self.period = period
            self.price = price
    
        def tell_info(self):
            print('<课程名:%s 周期:%s 价钱:%s>' % (self.name, self.period, self.price))
    
    
    # 三:课程
    # 1、创建课程
    course_obj1 = Course('python全栈开发', '6mons', 20000)
    course_obj2 = Course('linux运维', '5mons', 18000)
    
    # 2、查看课程的详细信息
    course_obj1.tell_info()
    course_obj2.tell_info()
    
    # 3、为班级关联课程对象
    class_obj1.related_course(course_obj1)
    class_obj2.related_course(course_obj2)
    class_obj3.related_course(course_obj1)
    
    class_obj1.tell_course()
    class_obj2.tell_course()
    class_obj3.tell_course()
    
    school_obj1.tell_class()
    school_obj2.tell_class()
    
    class Student:
        pass
    
    
    1、练习上课作业讲解的面向对象代码,明天默写
    2、基于上课作业讲解的面向对象代码,扩写Student类
    3、加入序列化与反序列化操作
    4、对象之间的关联采用id5、可以通过id找到对应的文件,然后从文件中反序列化出执行的学校、班级、课程、学生对象
    
  • 相关阅读:
    解决子元素浮动,父元素高度变小的问题
    解决子元素设置margintop,效果到父元素上的问题
    应用部署时自动推送企业微信提醒
    自定义Gradle Task实现一键批量部署Springboot应用
    springboot中@PostConstruct、CommandLineRunner、BeanPostProcessor执行顺序
    win7 关闭防火墙
    Android 4.1模拟器访问服务器接口
    Android开发教程 葵花宝典第一层 初识Android
    Android开发教程 葵花宝典第四层 控件之 Toast Spinner RadioButton
    Android开发教程 葵花宝典第三层 控件之 Button CheckBox EditText TextView
  • 原文地址:https://www.cnblogs.com/zdw20191029/p/14553342.html
Copyright © 2011-2022 走看看