zoukankan      html  css  js  c++  java
  • 面向对象三大特性之多态

    面向对象三大特性的多态

    一、多态

    • 概念
    '''
    1、什么是多态?
        多态指的是同一种类型的实物,不同的形态
    
        - 父类:动物
            - 吃: eat
            - 叫: speak
    
        - 子类:
            - 猪:
                吃:eat
                    吧唧吧唧
                叫:speak
                    哼哼哼
                技能:
                    飞
    
            - 狗:
                吃:tian chi
                    舔 ji 舔 ji
                叫:tell
                    汪汪汪
                游泳
    
            - 猫:
                吃:chi
                    咬 ji 咬 ji
                叫:jaio
                    喵喵喵
    
    
        - 笔
            铅笔:
                写:def write():
                    写完可以擦掉
    
            钢笔:
    
                写:def xie():
                    写完可以用胶布粘掉
    
            毛笔:
                写:def xie_zi():
                    写完可以手撕,无法从写
    
    2、多态的目的:
            “多态”也被称之为“多态性”,目的是为了 在不知道对象具体类型的情况下,统一对象调用方法的规范(比如:名字)
    
            多态的表现“形式之一”就是继承:
                - 先抽象,再继承
    
                父类:定制一套统一的规范(比如:方法名统一)
                子类:遵循父类的统一的规范(比如:子类继承父类方法名的统一)
    
            注意:在python中不会强制限制子类必须遵循父类的规范,所以出现了抽象类
    '''
    
    • 代码
    # # 正面教材
    # #动物类
    # class Animal:
    #
    #     #方法吃
    #     def eat(self):
    #         pass
    #
    #     #方法叫
    #     def speak(self):
    #         pass
    #
    # #猪类
    # class Pig(Animal):
    #     def eat(self):
    #         print('吧唧....')
    #
    #     def speak(self):
    #         print('哼哼哼....')
    #
    # #猫类
    # class Cat(Animal):
    #     def eat(self):
    #         print('咬 ji 咬 ji ')
    #
    #     def speak(self):
    #         print('喵喵喵...')
    #
    # #狗类
    # class Dog(Animal):
    #     def eat(self):
    #         print('舔ji 舔ji')
    #
    #     def speak(self):
    #         print('汪汪汪...')
    #
    #
    # animal1 = Dog()
    # animal2 = Cat()
    # animal3 = Pig()
    #
    # #让动物们叫起来
    # animal1.speak()
    # animal2.speak()
    # animal3.speak()
    
    
    #反面教材
    #动物类
    class Animal:
    
        #方法吃
        def eat(self):
            pass
    
        #方法叫
        def speak(self):
            pass
    
    #猪类
    class Pig(Animal):
        def eat(self):
            print('吧唧')
    
        def speak(self):
            print('哼哼哼')
    
    #猫类
    class Cat(Animal):
        def chi(self):
            print('咬ji 咬ji')
    
        def jaio(self):
            print('喵喵喵')
    
    #狗类
    class Dog(Animal):
        def tian_chi(self):
            print('舔 ji 舔 ji')
    
        def wangwang_jiao(self):
            print('汪汪汪')
    
    animal1 = Dog()
    animal2 = Pig()
    animal3 = Cat()
    
    #让动物们叫起来
    animal1.speak()
    animal2.speak()
    animal3.speak()
    

    二、抽象类

    • 夺命三问
    '''
    1、什么是抽象类?
        在python中内置的abc模块中,有一个抽象类
    
    2、抽象类的作用:
        让子类必须遵循父类的编写规范
    
    3、如何实现抽象类?
        - 父类需要继承abc模块中,metaclass=abc.ABCMeta
        - 在父类的方法中,需要装饰上 abc.abstractmethod
    
    注意:在python中不推荐使用抽象类(耦合度极高,程序可扩展性极地)
    
    注意:子类必须按照父类的方法编写规范,缺一不可(只要父类中有几个抽象方法,子类就必须要定义几个)
    
    '''
    
    • 代码
    import abc
    #父类
    class Animal(metaclass=abc.ABCMeta):
    
        #方法:吃
        @abc.abstractmethod
        def eat(self):
            pass
    
        #方法:叫
        @abc.abstractmethod
        def speak(self):
            pass
    
    #子类
    #猪类
    class Pig(Animal):
    
        def eat(self):
            print('吧唧吧唧')
    
        def speak(self):
            print('哼哼哼')
    
        def run(self):
            pass
    
    pig_obj = Pig()
    print(pig_obj.speak())  #哼哼哼
    

    三、鸭子类型

    • 夺命三问
    '''
    1、什么是鸭子类型?
        不同的对象,只要长得像鸭子,动作行为像鸭子,那他就是鸭子
    
        鸭子类型也是多态的一种表现形式
    
    2、为什么要有鸭子类型?
        不同对象,先抽象出相同类型的方法,给他们定制一套统一的规范
        所有的类,在定义时都按照统一的规范进行编写
    
        - 多态的三种表现形式:
            - 继续父类:
                -耦合度高,程序可扩展性低
    
            - 继承抽象类:
                - 耦合度极高,程序的可扩展性极地
    
            - 鸭子类型:
                - 耦合度低,程序的可扩展性高
        注意:因为鸭子类型的耦合性低,可扩展性高,所以在python中强烈推荐鸭子类型
    
    '''
    
    
    • 代码
    #猪类
    class Pig:
        def eat(self):
            print('吧唧吧唧')
    
        def speak(self):
            print('哼哼哼')
    
    #猫类
    class Cat:
        def eat(self):
            print('咬ji咬ji ')
    
        def speak(self):
            print('喵喵喵')
    
    #狗类
    class Dog:
        def eat(self):
            print('舔 ji 舔 ji')
    
        def speak(self):
            print('汪汪汪')
    

    四、多态之炫技

    • 实例
    #多态之炫技:了解,面试时装逼用的
    
    #猪类
    class Pig:
        def eat(self):
            print('吧唧吧唧')
    
        def speak(self):
            print('哼哼哼')
    
    #猫类
    class Cat:
        def eat(self):
            print('咬 ji 咬 ji')
    
        def speak(self):
            print('喵喵喵')
    
    #狗类
    class Dog:
        def eat(self):
            print('舔 ji 舔 ji')
    
        def speak(self):
            print('汪汪汪')
    
    dog = Dog()
    pig = Pig()
    cat = Cat()
    
    # dog.speak()
    # pig.speak()
    # cat.speak()
    
    #多态之炫技
    # def SPEAK(animal):
    #     animal.speak()
    #
    # SPEAK(dog)
    # SPEAK(cat)
    # SPEAK(pig)
    
    str1 = 'yafeng is very handsome!!!'
    list1 = ['yafeng', 'is', 'very', 'handsome!!!']
    
    print(str1.__len__())  #26
    print(list1.__len__())  #4
    
    #自定义统计长度函数
    def LEN(obj):
        return obj.__len__()
    
    print(LEN(str1))  #26
    print(LEN(list1))  #4
    
    print(len(str1))  #26
    print(len(list1))  #4
    

    五、isinstance 与 issubclass

    • 理论基础
    '''
    isinstance 与 issubclass 是python的内置模块:
        - isinstance: 判断一个对象是否是另一个类的实例(isinstance还可以判断一个对象是否是一个已知的类型,类似type)
            - 如果是:True
            - 如果不是:False
    
        - issubclass: 判断一个类是否是另一个类的子类
            - 如果是:True
            - 如果不是:False
    '''
    
    
    • 实例
    #isinstance:
    class Foo:
        pass
    
    class Boo:
        pass
    
    foo_obj = Foo()
    boo_obj = Boo()
    
    print(isinstance(foo_obj, Foo))  #True
    
    print(isinstance(boo_obj, Foo))  #False
    
    
    #issubclass
    class Father:
        pass
    
    class Sub(Father):
        pass
    
    class Foo:
        pass
    
    print(issubclass(Sub, Father))  #True
    
    print(issubclass(Foo, Father))  #False
    

    六、classmethod 与 staticmethod

    • 理论基础
    '''
    1、classmethod 与 staticmethod都是python解释器内置的装饰器
    
    classmethod:
        是一个装饰器,给在类内部定义的方法装饰,将类内部的方法变为“类的绑定方法”。
    
    staticmethod:
        翻译:静态方法
        是一个装饰器,给在类内部定义的方法装饰,将类内部的方法变为“非绑定方法”
    
    - 对象的绑定方法:
        - 由对象来调用,由谁来调用,会将谁(对象)当做第一个参数传入。
    
    - 类的绑定方法:
        - 由类来调用,由谁来调用,会将谁(类)当做第一个参数传入。
    
    - 非绑定方法:
        - 可以由对象或类来调用,谁来调用都是一个普通方法(普通函数),方法需要传入几个参数,就得传入几个
    
    '''
    
    
    • 实例
    # #classmethod
    # class DB:
    #     __data = 'yafeng is very handsome!!!'
    #
    #     def __init__(self, user, pwd, role):
    #         self.user = user
    #         self.pwd = pwd
    #         self.role = role
    #
    #     #查看数据方法
    #     @classmethod
    #     def check_db(cls, user, pwd, role):  #cls--->指的是类
    #
    #         #在类方法内部定义调用类产生一个实例---->对象
    #         obj = cls(user, pwd, role)
    #
    #         #1、查看数据前,必须要通过校验
    #         if obj.user == 'yafeng' and obj.pwd == '666' and obj.role == 'admin':
    #             print('校验通过')
    #             print(cls.__data)
    #             return cls.__data
    #
    # DB.check_db('yafeng', '666', 'admin')
    # #校验通过
    # # yafeng is very handsome!!!
    
    
    # #staticmethod
    # import uuid  #用于产生随机字符串的模块
    #
    # print(uuid.uuid4())  #bf30df87-0071-4c8e-bd7d-cfb3cea7c260
    
    
    class Foo:
        @staticmethod
        def func(res):
            print(res)
    
    obj = Foo()
    
    #对象调用非绑定方法(此时需传参)
    obj.func(666)   #666
    
    #类调用非绑定方法
    Foo.func(123)   #123
    

    七、反射

    • 理论知识
    '''
    反射:
        反射指的是通过“字符串”对 对象的属性进行操作
    
        - hasattr:通过“字符串”判断对象的属性或方法是否存在
    
        - getattr:通过“字符串”获取对象的属性或方法
    
        - setattr:通过“字符串”设置对象的属性或方法
    
        - delattr:通过“字符串”删除对象的属性或方法
    
        注意:反射的四个方法是python内置的
    '''
    
    • 举例
    # class Foo:
    #     def __init__(self, x, y):
    #         self.x = x
    #         self.y = y
    #
    #
    # foo_obj = Foo(10, 20)
    #
    # #hasattr
    # #通过字符串x 判断对象中是否有x属性
    # print(hasattr(foo_obj, 'x'))  #True
    # print(hasattr(foo_obj, 'y'))  #True
    # print(hasattr(foo_obj, 'z'))  #False
    #
    #
    # #getattr
    # res = getattr(foo_obj, 'x')
    # print(res)  #10
    #
    # #若属性不存在,也可以自定义返回的默认值
    # res = getattr(foo_obj, 'z', '默认值')
    # print(res)  #默认值
    #
    # #setattr
    # #为foo_obj 设置一个属性z, 值为30
    # # res = setattr(foo_obj, 'z', 30)
    # # print(res)   #*****不可以这么玩None
    #
    # setattr(foo_obj, 'z', 30)
    # print(hasattr(foo_obj, 'z'))  #True
    # res = getattr(foo_obj, 'z')
    # print(res)   #30
    #
    # #delattr
    # delattr(foo_obj, 'x')
    # print(hasattr(foo_obj, 'x'))  #False
    
    
    • 反射应用
    #反射应用
    class File_control:
        def run(self):
            while True:
                #让用户输入上传或下载功能的命令:
                user_input = input('请输入 上传(upload)或 下载(download) 的功能:').strip()
    
                #通过用户输入的字符串判断方法是否存在,然后调用相应的方法
                if hasattr(self, user_input):  #  if  True:
                    func = getattr(self, user_input)   #拿到内容
    
                    func()
    
                else:
                    print('输入有误...')
    
        def upload(self):
            print('文件正在上传...')
    
        def download(self):
            print('文件正在下载...')
    
    file_obj = File_control()
    file_obj.run()
    '''
    请输入 上传(upload)或 下载(download) 的功能:upload
    文件正在上传...
    请输入 上传(upload)或 下载(download) 的功能:download
    文件正在下载...
    请输入 上传(upload)或 下载(download) 的功能:
    '''
    
  • 相关阅读:
    Django 之 ORM
    python 变量问题 提问有大佬知道吗?
    celery 使用详解
    ubuntu 网络图标消失问题解决
    django + uwsgi 部署上线
    Python pip常用源地址
    ConfigParser 模块 使用
    Mysql 远程登录问题解决
    商城项目 从设想到实现
    硬盘上有打开的锁和感叹号标志如何解决(win10系统)
  • 原文地址:https://www.cnblogs.com/yafeng666/p/11950982.html
Copyright © 2011-2022 走看看