• 面向对象-三大特性


    一、组合:

    夺命三问:

    1.什么是组合?

    ​ 组合指的是一个对象中,包含另一个或多个对象

    2.为什么要使用组合?

    ​ 减少代码的冗余

    3.如何使用组合?

    耦合度:

    ​ -耦合度越高:程序的可扩展性越低

    ​ -耦合度越低:程序的可扩展性越高

    总结:

    ​ -继承:

    ​ 继承是类与类的关系,子类继承父类的属性/方法,子类与父类是一种’‘从属’‘关系。

    ​ -组合:

    ​ 组合是对象与对象的关系,一个对象拥有另一个对象中的属性/方法,是一种什么有什么的关系。

    #继承
    #父类
    # class People:
    #     def __init__(self,name, age, sex, year, month, day):
    #         self.name = name
    #         self.age = age
    #         self.sex = sex
    #         self.year = year
    #         self.month = month
    #         self.day = day
    #
    #     def tell_birth(self):
    #         print(f'''
    #         ========出生年月日============
    #             年:{self.year}
    #             月:{self.month}
    #             日:{self.day}
    #         '''
    #         )
    #
    # #老师类
    # class Teacher(People):
    #     def __init__(self, name, age, sex, year, month, day):
    #         super().__init__(name, age, sex, year, month, day)
    # #学生类
    # class Student(People):
    #     def __init__(self, name, age, sex, year, month, day):
    #         super().__init__(name, age, sex, year, month, day)
    #
    # tea1 = Teacher('tank', 17, 'male', 2002, 6, 6)
    # stu1 = Student('HCY', 109, 'female', 1910, 11, 11)
    # print(tea1.name, tea1.age, tea1.sex)
    # tea1.tell_birth()
    # print(stu1.name, stu1.age, stu1.sex)
    # stu1.tell_birth()
    
    #组合实现
    class People:
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    #老师类
    class Teacher(People):
            def __init__(self, name, age, sex):
                super().__init__(name, age, sex)
    #学生类
    class Student(People):
        def __init__(self,name, age, sex):
            super().__init__(name, age, sex)
    #日期类
    class Date:
        def __init__(self, year, month, day):
            self.year = year
            self.month = month
            self.day = day
        def tell_birth(self):
            print(f'''
            ========出生年月日==========
                年:{self.year}
                月:{self.month}
                日:{self.day}
            '''  )
    # tea1 = Teacher('tank', 17, 'male')
    # print(tea1.name, tea1.age, tea1.sex)
    # date_obj = Date(1995,1,26)
    # tea1.date_obj = date_obj
    # print(tea1.date_obj.year, tea1.date_obj.month, tea1.date_obj.day)
    # tea1.date_obj.tell_birth()  #得到tell_birth属性结果
    
    stu1 = Student('kangheng', 50, 'female')
    date_obj1 = Date(1949, 5, 20)
    #学生对象中包含一个自定义日期对象
    stu1.date_obj1 = date_obj1
    print(stu1.date_obj1.year, stu1.date_obj1.month, stu1.date_obj1.day)    #1949 5 20
    stu1.date_obj1.tell_birth()
    '''
    结果:
     ========出生年月日==========
                年:1949
                月:5
                日:20
    '''
    

    继承json模块中JSONEncode,并派生出新的功能。

    '''
    练习需求:
       选课系统:
        1、有学生、老师类,学生与老师有属性'名字, 年龄, 性别,课程列表'
        2、方法:老师与学生可以添加课程,打印学习/教授课程。
        3、课程对象:
            -属性:
                -课程名字
                -课程价格
                -课程周期
            -方法:
                -打印当前课程信息
        #组合实现
    '''
    class People:
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
        #添加课程
        def add_course(self, course_obj):    #self--->stu1
            # self.course_name = course_name
            # self.course_price = course_price
            # self.course_time = course_time
            # self.course_list.append(course_obj) #[课程对象1, 课程对象2,....]
            self.course_list.append(course_obj) #[python_obj, go_obj]
        #打印当前对象中课程列表的所有课程信息
        #--->打印所有课程
        def tell_all_course_info(self):  #self---->stu1
            #从当前对象中课程列表中取出所有的课程对象
            # self.course_list == [python_obj, go_obj]
            for course_obj in self.course_list:
                #1.course_obj --->python_obj
                #2.course_obj--->go_obj
                #通过课程对象,打印课程信息方法
                course_obj.tell_course_info() #python_obj.tell_course_info()    go_obj.tell_course_info()
    
    class Student(People):
        def __init__(self, name, age, sex):
           super().__init__(name, age, sex)
           #为当前对象添加课程列表属性----》【】
           self.course_list = []
    
    class Teacher(People):
        def __init__(self, name, age, sex):
            super().__init__(name, age, sex)
            #为当前对象添加课程列表:--->[]
            self.course_list = []
    
    #定义一个课程类:课程有:课程名称,课程价格,课程周期
    class Course:
        def __init__(self,course_name, course_price, _course_time):
            self.course_name = course_name
            self.course_price = course_price
            self.course_time = _course_time
        #定义打印课程方法:只打印当前课程信息
        def tell_course_info(self):
            print(f'''
            ===========课程信息如下==========
            课程名称:{self.course_name}
            课程价格:{self.course_price}
            课程周期:{self.course_time}
            ''')
    
    #学生对象stu1: 属性:name, age, sex ,course_list  方法:add_course,tell_all_course_info
    stu1 = Student('han', 18, 'female')
    #课程对象:属性:course_name, course_price, course_time, 方法:tell_course_info
    python_obj = Course('python', 20000, 6)
    go_obj = Course('go', 28000, 5)
    
    #学生调用添加课程功能
    stu1.add_course(python_obj)
    stu1.add_course(go_obj)
    
    #学生调用打印, 学生课程列表中所有课程的信息
    stu1.tell_all_course_info()
    

    二、封装:

    夺命三问:

    1、什么是封装?

    ​ 封:比如将一个袋子,封起来

    ​ 装:比如将一堆小猫,小狗和jason装在袋子里

    ​ #对象--->相当于一个袋子

    ​ 封装指的是可以将一堆属性和方法,封装到对象中

    ​ ps:对象就好比一个“袋子/容器”,可以存放一对属性和方法。

    ​ ps:存不是目的,目的是为了取,可以通过‘‘对象.’’的方式获取属性或方法

    2、为什么要封装?

    ​ 可以通过‘’对象.‘’的方式‘’存放/获取‘’属性或方法。

    ​ 对象拥有‘’.‘’的机制

    ​ 方便数据的存取

    ​ 节省内存空间

    3、如何封装?

    class User:
        x = 10
        def func(self):
            pass
     obj = User()
     obj.y = 20
     obj----->x, func ,y
    

    三、访问限制机制

    夺命三问:

    ​ 1、什么是访问限制机制?

    ​ 凡是在类内部定义的属性或方法,以__开头的属性或方法名,都会被限制,外部不能”直接访问“该属性原型

    PS:看着像该属性或方法被隐藏起来了

    python特有的:

    注意:凡是在类内部定义 _ _ 开头的属性或方法,都会变形为 _ 类名__ __ 属性/方法

    2、为什么要有访问限制?

    ​ 比如:将一些隐私的数据,隐藏起来,不让外部轻易获取

    ​ -接口:

    ​ 可以将一对数据封装成一个接口, 可以让用户调用接口

    ​ 并且通过相应的逻辑,最后再将数据返回给用户

    3、如何实现?

    # #demo1
    # class User:
    #     #__开头的属性
    #     __name = 'tank'  #__name 变形为----》_类名__name
    #     #__开头的方法
    #     def __run(self):
    #         print('tank is running...')
    
    # print(User.__name)  #type object 'User' has no attribute '__name'
    # obj = User()
    # print(obj._User__name)  #tank
    #
    #
    # #demo2
    # class User:
    #     #__开头的属性
    #     __name = 'tank' #__name 变形为---》_类__name
    #     __age = 17
    #     __sex = 'male'
    #     __ID = '123914120851023124'
    #     __bal = 1231513
    #     #校验接口,获取用户信息
    #     def parse_user(self, username, password):
    #         if username == 'tank' and password == '123':
    #             print(f'''
    #             通过验证,获取用户信息。
    #             用户名:{self.__name}
    #             用户年龄:{self.__age}
    #             用户性别:{self.__sex}
    #             身份ID:{self.__ID}
    #             用户资产:{self.__bal}
    #             ''')
    #         else:
    #             print('校验失败,无法查询用户信息')
    #     #__开头的方法:
    #     def __run(self):
    #         print('tank is running...')
    # obj = User()
    # obj.parse_user('tank', '123')
    
    #demo3
    class ATM:
        #取钱功能:
        #1.插如磁卡
        def __insert__card(self):
            print('开始插卡...')
            pass
        #2.输入密码
        def __input_pwd(self):
            print('请输入密码...')
            pass
        #3.输入取款金额
        def __input_bal(self):
            print('请输入取款金额...')
            pass
        #4.吐钱
        def __output_money(self):
            print('开始吐钱...')
        #5.打印流水账单
        def __print_flow(self):
            print('打印流水账单')
        #取款顺序规范接口
        def withdraw(self):
            #1.插入磁卡
            self.__insert__card()
            #2.输入密码
            self.__input_pwd()
            #3.输入取款金额
            self.__input_bal()
            #4.吐钱
            self.__output_money()
            #5.打印流水账单
            self.__print_flow()
    
    amt_obj = ATM()      #生成一个对象
    amt_obj.withdraw()   #调用方法接口
    

    四、property

    夺命三问:

    1.什么是property?
        是一个python内置的装饰器,可以装饰在"类内部的方法"上。
        可以将该方法调用方式由 ----> 对象.方法() ---> 对象.方法
    
    2.为什么用property?
        PS: 在某些场景下,调用的方法只是用来获取计算后的某个值。
        PS: 必须通过 对象.方法() 方式调用,让该方法看起来像动词。
    
        让名词的方法,调用时更为合理。
        目的是为了,迷惑调用者,调用的方法误以为是 属性。
    
    3.如何用?
    
    # 需求: 计算人体 bmi 指数
    # 体重 / 身高的平方
    # value = weight / (height * height)
    class User:
        def __init__(self, name, weight, height):
            self.__name = name
            self.weight = weight
            self.height = height
    
        # 获取bmi指数方法
        @property
        def bmi(self):
            # return self.weight / (self.height * self.height)
            return self.weight / (self.height ** 2)
    
    
        @property
        def name(self):
            return self.__name
    
        # 了解: 设置被property装饰后的方法
        # 注意: 需要修改的方法名字要与被property装饰器后的方法一样
        @name.setter
        def name(self, value):  # '赵shuai兵' --- 》 value
            self.__name = value
    
        @name.deleter
        def name(self):  # 删除属性
            del self.__name
    
    
    user_obj = User('HCY', 100, 1.9)
    
    # user_obj.bmi()()
    # print(user_obj.bmi())
    
    
    # user_obj.bmi()
    print(user_obj.bmi)
    
    # 报错
    # user_obj.bmi() = 29
    # user_obj.bmi = 29
    
    # print(user_obj.name())
    # print(user_obj.name)
    
    # 修改属性
    # user_obj.name = '赵shuai兵'
    #
    # print(user_obj.name)
    
    
    # 删除属性
    # del user_obj.name
    # print(user_obj.name)
    
    
    
  • 相关阅读:
    64位操作系统Visual Studio连接本机oracle的问题
    解决Oracle启动失败
    通过应用程序域AppDomain加载和卸载程序集
    C#应用程序实现单例模式
    不实现 INotifyPropertyChanged接口也能实现数据绑定
    WPF弹出“选择文件夹”对话框
    Linux常用命令
    markedown基本语法
    git使用
    用户打开浏览器,输入buidu.com页面展示百度首页。整个过程发生了什么?
  • 原文地址:https://www.cnblogs.com/xy-han/p/11983182.html
Copyright © 2020-2023  润新知