zoukankan      html  css  js  c++  java
  • 🍔类的继承, 多继承, 属性查找, 类的类型与抽象

    引入

    1.什么是继承

    • 继承是一种新建类的方式, 新建的类称为子类, 被继承的类称为父类
    • 继承的特性 : 子类会遗传父类的属性
    • 继承是类与类之间的关系

    2.为什么使用继承 (作用)

    • 使用继承可以减少代码的冗余
    • 示例:
    不使用继承时编写多个类
    class Animal:
        def run(self):
            print("奔跑")
        
        def eat(self):
            print("吃东西")
            
    class Duck:
        def run(self):
            print("奔跑")
            
        def eat(self):
            print("吃东西")
        
        def speak(self):
            print("嘎嘎嘎")
    
    class Pig:
        def run(self):
            print("奔跑")
    
        def eat(self):
            print("吃东西")
    
        def speak(self):
            print("咕咕咕")
    
    class Person:
        def run(self):
            print("奔跑")
    
        def eat(self):
            print("吃东西")
    
        def speak(self):
            print("呵呵呵")
            
    使用继承编写多个类
    class Animal:
        def run(self):
            print("奔跑")
    
        def eat(self):
            print("吃东西")
            
    class Duck(Animal):
        def speak(self):
            print("嘎嘎嘎")
        
    class Pig(Animal):
        def speak(self):
            print("咕咕咕")
            
    class Person(Animal):
        def speak(self):
            print("呵呵呵")
            
    #可以明显感觉到代码量减少        
    

    一.类(对象)的继承

    • Python中一切皆对象, 所以类也是对象
    • Python中支持一个类同时继承多个父类 (多继承)
    class Animal:
        def run(self):
            print("跑起来")
            
    class Work:
        def doing(self):
            print("敲代码")
            
    class Person(Animal,Work):  # 可以继承很多个类,用","隔开
        def eat(self):
            print("吃东西")
    
    • __bases__ : 查看对象继承的类
    print(Person.__bases__)  # (<class '__main__.Animal'>, <class '__main__.Work'>) 两个
    

    二.属性查找顺序

    1.多继承属性查找顺序

    • 多继承存在属性重复问题, 多个父类中存在着相同的属性, 那么对象该选择哪个属性使用呢?

    • 按照右边顺序查找 : 对象自己----->类----->父类 (多个父类,从左到右的先后顺序来找)

    class Shawn:
        def Am(self):
            print("i am from Shawn")
    
    class Pai:
        def Am(self):
            print("i am from Pai")
    
    class Da:
        def Am(self):
            print("i am from Da")
    
    class Xing(Pai,Shawn,Da):  # 继承了三个父类,查找顺序:从左到右
        pass
    
    start = Xing()
    
    start.Am()  # i am from Pai (找到的是最左边的)
    

    2.属性嵌套查找顺序 (多层继承)

    • 对象的属性 (attribute) : 我们一般是指对象的属性和方法
    • 多层继承关系的属性查找顺序, 永远是从最下层开始找,调用自己self.[属性]
    • 以下示例的数查找顺序 : 对象自己----->对象的类----->父类----->父类.....

    ps : Ctrl + 鼠标右键 快速跳转到属性 / 方法位置, 有时并不准确

    class Bar1(object):
        def Foo1(self):
            print("i am Bar1_Foo1")
    
        def Foo2(self):
            print("i am Bar1_Foo2")
            self.Foo1()  ###
    
    class Bar2(Bar1):
        def Foo1(self):
            print("i am Bar2_Foo1")
    
    obj = Bar2()
    obj.Foo2()
    '''输出
    i am Bar1_Foo2   (对象自己没有到父类去找)
    i am Bar2_Foo1   (执行到"self.Foo1()"后又返回来从最开始找)
    '''
    

    三.新式类与经典类

    1.新式类

    • 继承了 object 的类以及该类的子类, 都是新式类 (Python3中统一都是新式类)
    • Python3 中如果一个类没有继承任何类, 则默认会继承 object 类, 也就是Python3中所有的类都是新式类
    在"Python3"中
    class Default:  # 默认继承"object"
        pass
    
    print(Default.__bases__)  # (<class 'object'>,)
    

    2.经典类

    • 没有继承 object 的类以及该类的子类, 都是经典类 (只有Python2中才区分新式类和经典类)
    • Python2 中如果一个类没有继承任何类, 它不会继承object 类, 所以Python2 中才有经典类
    在"Python2"中
    class Default(object):  # 新式类
        pass
    
    class Animal:  # 经典类
        pass
    
    "Python2"中"print"语法
    print Default.__bases__  # (<class 'object'>,)
    print Animal.__bases__   # ()
    

    ps : 新式类与经典类的属性查找顺序是不一样的

    五.继承与抽象

    • 继承描述的是子类与父类之间的关系,是一种什么是什么的关系

    • 要找出这种关系,必须先抽象再继承,抽象即抽取类似或者说比较像的部分

    1.抽象

    • 将佩奇和乔治两对象比较像的部分抽取成类
    • 将人,鸭,猪这三个类比较像的部分抽取成父类
    • 抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)

    09be5c7f8cf368ce904a0658023c06a

    2.继承

    • 基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构

    06be7dec293e1dc8d345942b54b0bf7

    • 继承的应用
    class People(object):
        school = "蟹堡王餐厅"
    
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    class Staff(People):
        def sell(self):
            print(f"{self.name}正在卖蟹堡")
    
    class Boss(People):
        def payoff(self,obj,money):
            print(f"{self.name}给{obj.name}发了{money}元工资")
            obj.money = money
    
    S1 = Staff("海绵宝宝",20,"male")
    B1 = Boss("蟹老板",18,"male")
    
    S1.sell()         # 海绵宝宝正在卖蟹堡
    B1.payoff(S1,300) # 蟹老板给海绵宝宝发了300元工资
    print(S1.money)   # 300
    

    六.Python为类内置的特殊属性 (了解)

    [类名].__name__   # 类的名字(字符串)
    [类名].__doc__    # 类的文档字符串
    [类名].__base__   # 类的第一个父类(在讲继承时会讲)
    [类名].__bases__  # 类所有父类构成的元组(在讲继承时会讲)
    [类名].__dict__   # 类的字典属性
    [类名].__module__ # 类定义所在的模块
    [类名].__class__  # 实例对应的类(仅新式类中)
    

    七.类的派生

    类的派生

    八.菱形继承问题

    面说到Python支持多继承, 但新式类与经典类的属性查找顺序是不一样的

    菱形继承问题

  • 相关阅读:
    table常用功能总结
    oracle中number类型的数据使用as string 得到的值为null
    Oracle连接超时
    VS重新生成后仍然执行旧代码
    .NET 环境中使用RabbitMQ
    使用CLR Function代替T-SQL函数,优化检索效率
    SQL Server CLR 使用 C# 自定义存储过程和触发器
    OrderBy排序和IComparer的使用
    System.net.mail 使用ssl发送邮件失败
    C#利用CDO.Message发送邮件
  • 原文地址:https://www.cnblogs.com/songhaixing/p/14182488.html
Copyright © 2011-2022 走看看