• 面向对象的组合、封装、多态


    组合:

      组合指的是一个对象中的属性,是另一个对象.

      目的:减少代码的冗余

    例子:

    1.学生类,老师类, 学生和老师都有课程属性, 每一门课程都是一个对象.
    课程: 课程名字,课程周期,课程价钱

    2.学生和老师都有选择课程的功能, 还有打印所有课程的功能.
    class People:
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        # 添加一门课程方法
        def add_course(self, course_obj):
            self.course_list.append(course_obj)
    
        # 打印当前对象中所有课程的课程信息
        def tell_all_course(self):
            # 拿到当前对象的课程列表,列表中存放的是一个个的课程对象
            for course_obj in self.course_list:
    
                # 每一个课程对象调用查看课程信息的方法
                course_obj.tell_course_info()
    
    class Teacher(People):
        def __init__(self, name, age, sex):
            super().__init__(name, age, sex)
            # 用来存放课程对象
            self.course_list = []
    
    
    class Student(People):
        def __init__(self, name, age, sex):
            super().__init__(name, age, sex)
            self.course_list = []
    
    # 课程类
    class Course:
        def __init__(self, course_name, course_period, course_price):
            # 课程名称周期价格
            self.course_name = course_name
            self.course_period = course_period
            self.course_price = course_price
    
        def tell_course_info(self):
            print(f'''
            课程名称: {self.course_name}
            课程周期: {self.course_period}
            课程价钱: {self.course_price}
            ''')
    
    
    tea1 = Teacher('tank', 17, 'male')
    stu1 = Student('张全蛋', 20, 'female')
    python_obj = Course('python', 6, 2.0)
    linux_obj = Course('linux', 6, 1.0)
    
    # 添加python与linux课程
    tea1.add_course(python_obj)
    tea1.add_course(linux_obj)
    # tea1.course_list[0].tell_course_info()
    tea1.tell_all_course()

    封装

    封装指的是把一堆属性(特征与技能)封装到一个对象中.

    存数据的目的是为了取, 对象可以"."的方式获取属性.

    比喻: 对象就好比一个袋子, 袋子里面装一堆属性.

    封装的目的为了方便存取,可以通过对象.属性的方式获取属性.

    如何封装
    特征: 变量 ---> 数据属性
    技能: 函数 ---> 方法属性

    在类内部,定义一堆属性(特征与技能).
    通过 对象.属性 = 属性值

    访问限制机制: 通过接口访问
    1.什么是访问限制机制? 在类内部定义, 凡是以__开头的数据属性与方法属性, 都会被python内部隐藏起来,让外部不能"直接"访问类内部的__开头的属性.
    比如:__name = 'tank' 此时直接打印__name 会报错,没有__name的属性

      2.访问限制机制的目的?
    一堆隐私的属性与不能被外部轻易访问的属性, 可以隐藏起来,不被外部直接调用.
    好处:
    对重要数据获取的逻辑更加严谨, 进而保证了数据的安全.

    
    

    接口: 隐私属性可以通过封装一个接口,在接口内做业务逻辑的处理,再把数据返回给调用者.

    
    

    注意: 在python中,不会强制限制属性的访问,类内部__开头的属性,只是做了一种变形.
    若想直接访问, 调用变形后的名字即可.
    class Foo:
    __name = 'tank' # ---> _类名__属性名

    
    
    class Foo:
    
        # 数据属性
        __name = 'tank'
    
        # 方法属性
        def __run(self):
            print('running..')
    
        # 接口: 获取数据接口
        def get_name(self):
            return self.__name
    
        def set_name(self):
            self.__name = 'jason_sb'
    
    foo = Foo()
    print(foo.__name)  #报错没有__name
    res = foo.get_name()
    print(res)   #接口调用得到__name
    print(foo._Foo__name)  # --> _Foo__name   #或者直接用 _类名__属性名调用  
    foo.set_name()# 通过接口修改被隐藏的属性值
    print(foo.get_name())
    
    
    class Teacher:
    
        def __init__(self, name, age, sex):
            self.__name = name
            self.__age = age
            self.__sex = sex
    
        # 接口: 打印用户信息接口
        def get_info(self):
            # 用户认证
            user = input('user: ').strip()
            pwd = input('pwd: ').strip()
            if user == 'tank' and pwd == '123':  #通过密码认证,然后接口再调用打印隐藏属性
                print(f'''
                姓名: {self.__name}
                年龄: {self.__age}
                性别: {self.__sex}
                ''')
    
        # 接口: 修改用户信息接口
        def set_info(self, name, age, sex):
            # str1 = 'string'  # str('string')
            if not isinstance(name, str):
                raise TypeError('名字必须要使用字符串')
    
            if not isinstance(age, int):
                raise TypeError('年龄必须是数字')
    
            if not isinstance(sex, str):
                raise TypeError('性别必须要使用字符串')
    
            self.__name = name
            self.__age = age
            self.__sex = sex
    
    
    tea1 = Teacher('tank', 17, 'male')
    # tea1.get_info()
    tea1.set_info('jason_sb', 101, 'female')
    tea1.get_info()
    class ATM:
        # 1.插卡
        def __insert_card(self):
            print('插卡')
            pass
    
        # 2.输入密码
        def __input_pwd(self):
            print('密码验证')
            pass
    
        # 3.输入取款金额
        def __input_money(self):
            print('输入金额')
            pass
    
        # 4.开始吐钱
        def __get_money(self):
            print('执行吐钱')
            pass
    
        # 5.打印账单
        def __print_flow(self):
            print('打印账单')
            pass
    
        # 取钱直接接口   规定程序执行的顺序
        def withdraw(self):
            self.__insert_card()
            self.__input_pwd()
            self.__input_money()
            self.__get_money()
            self.__print_flow()
            print('取款程序执行完毕!')
    
    
    atm = ATM()
    atm.withdraw()

    property

    1. 什么是property
    python内置的装饰器, 主要是给类内部的方法使用.

    2. 为什么要用property
      在对象调用某个方法时,将对象.方法()变成对象.方法(看起来想一个普通的数据属性)
    obj.bmi() == obj.bmi

    - 如何使用property
      @property
      def 类内部的方法(self):

      如 @property

        def get_name(self):

      如果此时想要修改改方法的返回值,不能直接修改

        # 改
        @get_name.setter #get_name要与想修改返回值的方法名一致.setter是固定的单词
        def set_name(self, val):
        self.name = val

        # 删除
        @get_name.deleter
        def del_name(self):
        del self.name
    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 * self.height)
    
        # 了解
        @property
        def get_name(self):
            return self.name
    
        #
        @get_name.setter
        def set_name(self, val):
            self.name = val
    
        # 删除
        @get_name.deleter
        def del_name(self):
            del self.name
    
    
    p = People('jason', 200, 1.6)
    # print(p.bmi())  # 打印动词,看起来不合理
    print(p.bmi)  # ---> p.bmi()
    
    # 注意: 不能对被装饰过的方法属性修改.
    # p.bmi = 18
    
    
    # # 了解: 若真要通过此方法修改属性,可以通过另一种方式修改.
    # print(p.get_name)
    # p.set_name = 'tank'
    # print(p.get_name)
    # # p.del_name()
    # # print(p.get_name)

     多态

    1.什么是多态?

      多态指的是同一种事物的多种形态.

    2.多态的目的:

    多态也称之为多态性, 在程序中继承就是多态的表现形式.
    多态的目的是为了, 让多种不同类型的对象, 在使用相同功能的情况下,调用同一个名字的方法名.
    父类: 定义一套统一的标准.
    子类: 遵循父类统一的标准.
    多态的最终目的: 统一子类编写的规范, 为了让使用者更方便调用相同功能的方法.

    3.如何实现:
    - 继承

    注意: 在python中,不会强制要求子类必须遵循父类的一套标准,所以出现了抽象类.

    class Animal:
        #
        def eat(self):
            pass
    
        #
        def drink(self):
            pass
    
        #
        def speak(self):
            pass
    
    #
    class Pig(Animal):
    
        #
        def eat(self):
            print('猪在吃饭')
            pass
    
        #
        def drink(self):
            pass
    
        def speak(self):
            print('哼哼哼~~~')
    
    #
    class Cat:
        #
        def eat(self):
            print('猫在吃饭')
            pass
    
        #
        def drink(self):
            pass
    
        def speak(self):
            print('喵喵喵~~')
    
    #
    class Dog:
        #
        def eat(self):
            print('狗在吃饭')
            pass
    
        #
        def drink(self):
            pass
    
        def speak(self):
            print('汪汪汪~~~')
    
    # 正确教材
    pig = Pig()
    cat = Cat()
    dog = Dog()
    
    pig.speak()
    cat.speak()
    dog.speak()

     抽象类

    1.是什么?

       abc模块 abstract_class

    2.使用的目的?
      强制子类必须遵循父类的一套标准.

    3.如何使用
      import abc

      class 父类()在括号内写入 metaclass=abc.ABCMeta,然后在父类的方法里面加上@abc.abstractmethod这个装饰器

    子类里面必须要有父类里面所有装饰过的方法,不能少,但可以派生自己的反法

    import abc
    
    
    class Animal(metaclass=abc.ABCMeta):
    
        #
        @abc.abstractmethod
        def eat(self):
            pass
    
        #
        @abc.abstractmethod
        def drink(self):
            pass
    
        #
        @abc.abstractmethod
        def speak(self):
            pass
    
    #
    class Pig(Animal):          
        #
        def eat(self):
            print('猪在吃饭')
            pass
    
        #
        def drink(self):
            pass
    
    
        def speak(self):
            print('哼哼哼~~~')
    
    
        # 派生
        def run(self):
            pass
    
    
    pig = Pig()

     鸭子类型

    1. 什么是鸭子类型?
      在不知道当前对象是何物的情况下,但是你长得像鸭子,那么你就是鸭子类型.

      在python中,不推荐使用抽象类强制限制子类的定义,但是推荐  类都遵循鸭子类型.

    2. 继承:
      耦合性太高,程序的可扩展性差

    3. 鸭子类型:
      耦合度低,程序的可扩展性强

     多态炫技操作

    #
    class Pig:
        #
        def eat(self):
            print('猪在吃饭')
            pass
        #
        def drink(self):
            pass
        def speak(self):
            print('哼哼哼~~~')
    
    
    #
    class Cat:
        #
        def eat(self):
            print('猫在吃饭')
            pass
        #
        def drink(self):
            pass
        def speak(self):
            print('喵喵喵~~')
    
    #
    class Dog:
        #
        def eat(self):
            print('狗在吃饭')
            pass
        #
        def drink(self):
            pass
        def speak(self):
            print('汪汪汪~~~')
    
    dog = Dog()
    cat = Cat()
    pig = Pig()
    
    def BARK(animal):  # 自定义了一个函数
        animal.speak()
    
    BARK(dog)
    BARK(cat)
    BARK(pig)
    str1 = '1234'
    list1 = [1, 2, 3]
    
    print(str1.__len__())
    print(list1.__len__())
    
    def LEN(d):
        return d.__len__()
    
    print(LEN(str1))
    print(LEN(list1))
    
    print(len(str1))
    print(len(list1))
     
  • 相关阅读:
    Docker安装及简单使用
    常用编程语言注释符
    常用正则标记
    Android studio 使用startService报错:IllegalStateException
    Mybatis映射文件中#取值时指定参数相关规则
    IDEA Maven项目的Mybatis逆向工程
    循环结构
    每日思考(2020/03/05)
    分支结构
    每日思考(2020/03/04)
  • 原文地址:https://www.cnblogs.com/fjn839199790/p/11654384.html
Copyright © 2020-2023  润新知