繼承特性


繼承特性

一、什么是繼承

  • 繼承是一種新建類的方式,繼承了一個類,類中的屬性和方法就在子類中,類主要分為:父類/基類,子類/派生類

  • 新式類

  • 經典類

  • 沒有繼承object的類,就是經典類,python3中沒有經典類,python2中才有


class A(object):
    pass

class C(object):
    pass

class B(A, C):
    pass

# 類的其他內置屬性,__名字__
# 查看類的屬性和方法
print(B.__dict__)

# 查看類名
print(B.__name__)

# 查看B類的父類
print(B.__bases__)

{'module': 'main', 'doc': None}
B
(<class 'main.A'>, <class 'main.C'>)

二、繼承重用父類

類實例化會自動調用__init__如果類中沒有,去父類中找

class Person:
    school = 'hnnu'

class Teacher(Person):
    def __init__(self, name,age,level):
        self.name = name
        self.age = age
        self.level = level

class Student(Person):
    school = 'bj'

    def __init__(self, name, age, course):
        self.name = name
        self.age = age
        self.course = course


stu1 = Student('zhangsan', 18, 'python')
print(stu1.school)

stu1.school = 'xxx'
print(stu1.school)

bj
xxx

三、屬性的查找順序

先找到當前的對象—>類中找--->父類中找(注意多繼承)—>報錯(找不到)

四、多層繼承和多繼承

# 多層繼承

class A:
    a = 'aaa'

class B(A):
    b = 'bbb'

class C(B):
    c = 'ccc'

class D(C):
    d = 'ddd'

d = D()
print(d.a)

ddd

# 多繼承
class A:
    a = 'aaa'

class B:
    a = 'bbb'

class C:
    a = 'ccc'

class D(A,B,C):
    a = 'ddd'


d = D()
print(d.a)

ddd

四、菱形問題


# 繼承菱形問題: 新式類和經典類的查找順序不一樣
# 新式類的查找屬性:廣度優先
# 經典類:深度優先

class G():
    a = 'ggg'


class F(G):
    a = 'fff'


class E(F):
    a = 'eee'


class D(E):
    a = 'ddd'


class C(D):
    a = 'ccc'


class B(C):
    a = 'bbb'


class A(B, C, D):
    a = 'aaa'

a = A()
print(a.a)

# mro 列表,查看繼承順利列表(只在新式類中有)
print(A.mro())
print(A.__mro__)


  • 繼承菱形問題在python3中顯示的都是繼承一個類,不是object類, 新式類和經典類的查找順序是不一樣
  • 新式類(python3中全是新式類):廣度優先---從左側開始,一直往上找,找到菱形的頂點結束(不包含菱形頂點),繼續下一個繼承父類往上找,找到菱形的頂點結束(不包含括菱形的頂點),最后找到菱形頂點
  • 經典類(python2中才有):深度優先搜索---從左側開始,一直往上找,找到菱形頂點結束(包括菱形頂點),繼續下一個繼承父類往上找,找到菱形的頂點結束(不包含菱形頂點)

五、重用父類方法的兩種方式


class Person:
    school = 'hnnu'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def study(self):
        print('study...')


class Teacher(Person):
    def __init__(self, name, age, level):
        self.name = name
        self.age = age

        self.level = level


# 重用父類方法一
class Student1(Person):
    # 重用父類__init__方法
    def __init__(self, name, age, course):
        Person.__init__(self, name, age)
        self.course = course

    def study(self):
        Person.study(self)
        print(f'{self.name}學生在學習')


# 重用父類方法二
class Student2(Person):
    # 重用父類方法__init方法
    def __init__(self, name, age, course):
        # super() 會按照mro列表拿到父類對象
        # 對象來調用綁定方法,不需要傳遞第一個參數(self)
        super().__init__(name, age)

        # 經典類中必須這樣寫(py3中沒有經典類),但是在python3中都用上面那種方式寫
        super(Student2, self).__init__(name, age)
        self.course = course

    def study(self):
        Person.study(self)
        print(f'{self.name}學生在學習')

stu1 = Student1('web', 18, 'Python')
stu1.study()

stu2 = Student2('xiaomei', 19, 'Linux')
stu2.study()

study...
web學生在學習
study...
xiaomei學生在學習

  1. 總結,有繼承關系的時候,通常用super

  2. 指名道姓的方式在什么情況下用?

    • 沒有繼承關系
    • 如果繼承了多個父類,super是按照mro列表找,現在想指名道姓的用某個父類的某個方法,就需要指名道姓的使用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM