1. 程式人生 > >學習python課程第二十二天

學習python課程第二十二天

打印 以及 如何 語言 eve 查找 elf 關系 描述

一 . 類的繼承與派生 :

  1. 什麽是繼承:

    在程序中繼承是一種新建子類的方式, 新創建的類稱之為子類,或者派生類.

    被繼承的類稱之為父類,

    繼承描述的是一種遺傳關系, 子類可以重用父類的屬性.

  2. 為何要用繼承 :

    繼承可以減少類與類之間代碼冗余的問題.

  3. 如何繼承 :

    先抽象,再繼承

    抽象 :抽取出比較像的部分.. 最主要的作用是劃分類別 (可以隔離關註點, 降低復雜度.)

    繼承 :是基於抽象的結果,通過編程語言去實現它. 肯定是先經歷抽象這個過程,才能通過繼承的方式去表示

    出抽象的結構

    抽象只是分析和設計的過程中,一個動作或者說一個技巧. 可以通過抽象來得到類.

  示例 :

    # 在python中繼承的特點 : 有單繼承 和 多繼承

 

    class Parent1:

      pass

    class Parent2:

      pass

    class Sub1(Parent1):

      pass

    class Sub2(Parent1,Parent2):

      pass

  print(Sub1.__bases__) # 查看它的基礎,基本

  print(Sub2.__bases__)

      

  python2 與 python3中,繼承上的區別:

  新式類 : 但凡繼承object類的子類, 以及該子類的子子類...都稱之為新式類.

  

  經典類 : 沒有繼承object類的子類, 以及該子類的子子類...都稱之為經典類.

  

  只有在python2中才區分新式類與經典類. (在python中也寫上object,這個程序也可以在python2中兼容)

  

  4. 基於繼承解決類與類代碼冗余的問題 :

   在子類派生出的新功能中,如何重用父類的功能:

   方式一: 指名道姓的訪問某一個類中的函數,與繼承無關,

    class OldboyPeople: # 存放兩個類似的相同屬性. (父類)

      school = ‘Oldboy‘

      def __init__(self,name,age,gender):

        self.name = name

        self.age = age

        self.gender = gender

    

    class OldboyStudent(OldboyPeople) # 學生的類

      def choose_course(self):

        print(‘%s 正在選課‘ %self.name)

    class OldboyTeacher(OldboyPeople):

      def __init__(self,name,age,gender,level.salary):

        OldboyPeople.__init__(slef,name,age,gender) # 指名道姓的找到父類裏相同的屬性

        self.level = level

        self.salary = salary

      def score(self,stu,num):

        stu.num = num

        print(‘老師%s給學生%s打分%s‘ %(self,name,stu.name,num))

    

  5. 在單繼承的背景下屬性的查找:

    在單繼承背景下, 無論是新式類,還是經典類, 屬性查找順序都一樣.

    順序: 先 obj ---> 類 ---> 父類 --->......

    class Foo:

      def f1(self):

        print(‘Foo 1‘)

      def f2(self):

        print(‘Foo 2‘)

        self.f1() #obj.f1()

    class Bar(Foo):

      def f1(self):

        print(‘Bar f1‘) # 打印這個結果

  obj = Bar()

  obj.f2()

  

  6. 在多繼承背景下, 如果一個子類繼承了多個分支,但是多個分支沒有匯聚到一個非object類.

    無論新式類和經典類查找順序都一樣 :

    順序: 會按照從左到右的順序一個分支一個分支的查找下去

      A -->B-->E-->C-->F--D 最後在找object

    class F:

     pass

    class E:

     pass

    class B(E):

     pass

    class C(F):

     pass

    class D:

     pass

    class A(B,C,D):

     pass

  在多個繼承背景下, 如果一個子類繼承了多個分支,但是多個分支最終匯聚到一個非object類 (菱形繼承問題)

    

  新式類的查找方式 : 廣度優先查找 obj-->A-->B-->E-->C-->F-->D-->G-->object

  經典類的查找方式 : 深度優先查找 obj-->A-->B-->E-->G-->C-->F-->D

  

   這個查找順序都是基於C3算法得來的結果,

  C3 算法在python3裏有一個內置的方法,xx . mro() 在mro列表中存放著C3算法的結果, 它是在定義類的時候就

  開始計算了.

  不管是單繼承還是多繼承或者是菱形繼承, 都是按照C3算法的mro裏的結果列表的順序來查找.

  

  

  

  

  7. 用super方法來重用父類的功能.

  

  super(OldboyTeacher). 在python3中super可以不傳參數,調用該函數會得到一個特殊的對象,該對象是專門用來

    訪問父類中的屬性.

  強調 : super會嚴格參照當前類的mro列表依次查找屬性.

  # 在子類派生出的新功能中, 如何重用父類的功能:

    方式2 :

    

    class OldboyPeople:

      school = ‘oldboy‘

      def __init__(self,name,age,gender):

        self.name = name

        self.age = age

        self.gender = gender

      

    class OldboyTeacher(OldboyPeople):

      def __init__(self,name,age,gender,level,salary):

        super(OldboyTeacher,self).__init__(name,age,gender) #super本身不用傳參數

        self.level = level

        self.salary = salary

  註意 : 兩種方式都可以用,但是最好不要兩種方式混著用.

  

  總結 : 一般在搭建框架的時候才用到多繼承, 繼承這個方式以後能不用就不用, 好處確實是能減少代碼冗余,

  但是它把子類和父類的耦合加大. 程序的可讀性變差. 繼承可以用,但是一般在單繼承的場景下再用.

    

學習python課程第二十二天