天天看點

繼承的注意事項類屬性案例練習 | 手把手教你入門Python之六十四

上一篇: 繼承的使用 | 手把手教你入門Python之六十三 下一篇: Python2和Python3的差別 | 手把手教你入門Python之六十五 本文來自于千鋒教育在阿裡雲開發者社群學習中心上線課程 《Python入門2020最新大課》 ,主講人姜偉。

繼承的注意事項

在Python中,繼承可以分為單繼承、多繼承和多層繼承。

單繼承:⼦類隻繼承⼀個⽗類

繼承概念:⼦類⽤于⽗類的所有的⽅法和屬性。

不使用繼承:

繼承的注意事項類屬性案例練習 | 手把手教你入門Python之六十四

使用繼承:

繼承的注意事項類屬性案例練習 | 手把手教你入門Python之六十四

繼承文法:

class 類名(⽗類名):
    pass           
  • ⼦類繼承⾃⽗類,可以享受⽗類中已經封裝好的⽅法,不需要再次定義
  • ⼦類中應該根據職責,封裝⼦類特有的屬性和⽅法。

繼承的傳遞性

Dog類繼承⾃Animal,XiaoTianQuan⼜繼承⾃Dog類,那麼XiaoTianQuan類就具有了Animal類⾥的所有屬性和⽅法。

⼦類擁有⽗類以及⽗類的⽗類中封裝的所有屬性和⽅法。

思考:

XiaoTianQuan能否調⽤Animal的run()⽅法? XiaoTianQUan能夠調⽤Cat⾥的⽅法?

多繼承

⼦類可以擁有多個⽗類,并且具有所有⽗類的屬性和⽅法。

繼承的注意事項類屬性案例練習 | 手把手教你入門Python之六十四

文法格式:

class ⼦類名(⽗類名1,⽗類名2...)
    pass           

多繼承的使⽤注意事項

如果不同的⽗類中存在同名的⽅法,⼦類對象在調⽤⽅法時,會調⽤哪個⽗類的⽅法? 說明:開發中,應該盡量避免這種容易産⽣混淆的情況。如果多個⽗類之間存在同名的屬性後者⽅法,應該盡量避免使⽤多繼承。
繼承的注意事項類屬性案例練習 | 手把手教你入門Python之六十四

Python中的MRO

  • Python中針對類提供了⼀個内置屬性

    __mro__

    可以⽤來檢視⽅法的搜尋順序。
  • MRO 是

    method resolution order

    的簡稱,主要⽤于在多繼承時判斷⽅法屬性的調⽤順序。
print(C.__mro__)           

輸出結果:

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)           
  • 在調⽤⽅法時,按照

    __mro__

    的輸出結果從左⾄右的順序查找。
  • 如果再目前類中找到⽅法,就直接執⾏,不再向下搜尋。
  • 如果沒有找到,就順序查找下⼀個類中是否有對應的⽅法,如果找到,就直接執⾏,不再繼續向下搜尋。
  • 如果找到了最後⼀個類,依然沒有找到⽅法,程式就會報錯。
class A(object):
    def demo_a(self):
        print('我是A類裡的方法demo_a')
    
    def foo(self):
        print('我是A類裡的foo方法')


class B(object):
    def demo_b(self):
        print('我是B類裡的方法demo_b')

    def foo(self):
        print('我是B類裡的foo方法')

    

# python裡允許多繼承
class C(A, B):  # 如果不寫父類,python3以後,預設繼承自object
    pass

c = C()
c.demo_a()  # 我是A類裡的方法demo_a
c.demo_b()  # 我是B類裡的方法demo_b

# 如果兩個不同的父類有同名方法,有一個類屬性可以檢視方法的調用順序
c.foo()  # 我是A類裡的foo方法
print(C.__mro__)   # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)           

私有屬性繼承特點

class Animal(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.__money = 1000
    
    def eat(self):
        print(self.name + '正在吃東西')

    def __test(self):
        print('我是Animal類裡的test方法')


class Person(Animal):
    def __demo(self):
        print('我是Person裡的私有方法')


p = Person('張三', 18)
print(p.name)  # 張三
p.eat()  # 張三正在吃東西
# p.__test()  # 出錯
p._Person__demo()  # 自己類裡定義的私有方法  對象名._類名__私有方法()
p._Animal__test()  # 我是Animal類裡的test方法  可以通過 對象名._父類名__私有方法()調用

# 私有屬性和方法,子類不會繼承
# p._Person__test()  # 出錯  父類的私有方法,子類沒有繼承
# print(p._Person__money)  # 出錯
print(p._Animal__money)  # 1000           

新式類和舊式(經典)類

# -*- coding:utf8-*-
# 手動指定Student類繼承自object
class Student(object):
    pass

# 沒有指定Dog的父類,python3裡預設繼承自object
class Dog:
    pass           

object

是Python中所有對象的基類,提供了⼀些内置的屬性和⽅法,可以時候⽤

dir

函數檢視。

  • 新式類:以

    object

    為基類的類,推薦使⽤
  • 經典類:不以

    object

    為基類的類,不推薦使⽤
  • 在 Python3.x 以後定義類時,如果沒有指定⽗類,這個類會預設繼承⾃

    object

    ,是以,python3.x版本定義的類都是新式類。
  • 在Python2.x中定義類時,如果沒有指定⽗類,則不會繼承⾃

    object

    ,這個類是一個經典類。

為了保證代碼在Python2.x和Python3.x中都能夠運⾏,在定義類時,如果⼀個類沒有⽗類,建議統⼀繼承⾃

object

class 類名(object):
    pass           

配套視訊