1. 程式人生 > Python進階應用教學 >05 Python 類的繼承和多繼承

05 Python 類的繼承和多繼承

在面向物件的程式設計中,定義一個新的 class 的時候,可以從某個現有的 class 繼承,新的 class 稱為子類,而被繼承的 class 稱為基類、父類或超類。

Python 中繼承的語法如下:

class Parent:
    pass

class Child(Parent):
    pass
  • 在第 1 行,定義了父類 Parent;
  • 在第 4 行,定義了子類 Child,語法 Child(Parent) 表示類 Child 繼承於類 Parent。

子類繼承父類的屬性和方法,使得子類具有父類的屬性和方法,從而實現程式碼重用;同時,子類可以增加自己特有的方法。例如,下圖中定義了 3 個類,類 Teacher 與類 Student 繼承於類 Person,如圖所示:

  • 父類 Person 定義了屬性 name 和 age,定義了方法 introduce,這些屬性和方法被子類繼承
  • 子類 Teacher 定義了自己特有的屬性 salary,定義了自己特有的方法 showSalary
  • 子類 Student 定義了自己特有的屬性 grade,定義了自己特有的方法 showGrade

1. 在子類中增加屬性和方法

1.1 編寫父類 Person

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

    def introduce
(self): print('My name is', self.name) print('My age is', self.age)
  • 在第 2 行,定義構造方法 __init__,設定屬性 name 和 age
  • 在第 6 行,定義方法 introduce,列印屬性 name 和 age

1.2 編寫子類 Teacher

class Teacher(Person):
    def __init__(self, name, age, salary):
        self.name = name
        self.age = age
        self.
salary = salary def showSalary(self): print('My salary is', self.salary)
  • 在第 1 行,通過語法 Teacher(Person),定義繼承於 Person 的類 Teacher
  • 在第 5 行,在構造方法中,增加類 Teacher 特有的屬性 salary
  • 在第 7 行,定義方法 showSalary,列印屬性 salary

1.3 編寫子類 Student

class Student(Person):
    def __init__(self, name, age, grade):
        self.name = name
        self.age = age
        self.grade = grade

    def showGrade(self):
        print('My grade is', self.grade)
  • 在第 1 行,通過語法 Student(Person),定義繼承於 Person 的類 Student
  • 在第 5 行,在構造方法中,增加類 Student 特有的屬性 grade
  • 在第 7 行,定義方法 showGrade,列印屬性 grade

1.4 建立例項

teacher = Teacher('tom', 30, 5000)
teacher.introduce()
teacher.showSalary()
print()
student = Student('jerry', 10, 90)
student.introduce()
student.showGrade()
  • 在第 1 行,建立例項 teacher
    • 在第 2 行,呼叫父類方法 introduce
    • 在第 3 行,呼叫自己特有的方法 showSalary
  • 在第 5 行,建立例項 student
    • 在第 6 行,呼叫父類方法 introduce
    • 在第 7 行,呼叫自己特有的方法 showGrade

執行程式,輸出如下結果

My name is tom
My age is 30
My salary is 5000

My name is jerry
My age is 10
My grade is 90
  • 第 1 行到第 3 行,是 teacher 的輸出結果
  • 第 5 行到第 7 行,是 student 的輸出結果

2. 在子類中呼叫父類的構造方法

2.1 程式碼重複的問題

在前面的小節中,類 Person 的構造方法如下:

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

類 Teacher 的構造方法如下:

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

類 Student 的構造方法如下:

class Student(Person):
    def __init__(self, name, age, grade):
        self.name = name
        self.age = age
        self.grade = grade

在這 3 段初始化程式碼中,存在明顯的程式碼重複,我們希望:

  • 初始化類 Teacher 的屬性 name、age、salary 時,可以重用父類 Person 的初始化程式碼
  • 初始化類 Student 的屬性 name、age、grade 時,可以重用父類 Person 的初始化程式碼

2.2 編寫父類 Person

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

    def introduce(self):
        print('My name is', self.name)
        print('My age is', self.age)
  • 在第 2 行,定義構造方法 __init__,設定屬性 name 和 age
  • 在第 6 行,定義方法 introduce,列印屬性 name 和 age

2.3 編寫子類 Teacher

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

    def showSalary(self):
        print('My salary is', self.salary)
  • 在第 1 行,通過語法 Teacher(Person),定義繼承於 Person 的類 Teacher
  • 在第 3 行,通過語法 Person.__init(self, name, age)__ 呼叫父類的構造方法 __init__,對屬性 name 和 age 進行設定
  • 在第 4 行,在構造方法中,增加類 Teacher 特有的屬性 salary
  • 在第 6 行,定義方法 showSalary,列印屬性 salary

2.4 編寫子類 Student

class Student(Person):
    def __init__(self, name, age, grade):
        Person.__init__(self, name, age)
        self.grade = grade

    def showGrade(self):
        print('My grade is', self.grade)
  • 在第 1 行,通過語法 Student(Person),定義繼承於 Person 的類 Student
  • 在第 3 行,通過語法 Person.__init(self, name, age)__ 呼叫父類的構造方法 __init__,對屬性 name 和 age 進行設定
  • 在第 4 行,在構造方法中,增加類 Student 特有的屬性 grade
  • 在第 6 行,定義方法 showGrade,列印屬性 grade

2.5 建立例項

teacher = Teacher('tom', 30, 5000)
teacher.introduce()
teacher.showSalary()
print()
student = Student('jerry', 10, 90)
student.introduce()
student.showGrade()
  • 在第 1 行,建立例項 teacher
    • 在第 2 行,呼叫父類方法 introduce
    • 在第 3 行,呼叫自己特有的方法 showSalary
  • 在第 5 行,建立例項 student
    • 在第 6 行,呼叫父類方法 introduce
    • 在第 7 行,呼叫自己特有的方法 showGrade

執行程式,輸出如下結果

My name is tom
My age is 30
My salary is 5000

My name is jerry
My age is 10
My grade is 90
  • 第 1 行到第 3 行,是 teacher 的輸出結果
  • 第 5 行到第 7 行,是 student 的輸出結果

3. 多繼承

定義一個新的 class 的時候,可以從多個現有的 class 繼承,如果繼承多個父類,稱為多繼承。Python 中多繼承的語法如下:

class Father:
    pass

class Mother:
    pass

class Child(Father, Mother):
    pass
  • 在第 1 行,定義了父類 Father
  • 在第 4 行,定義了父類 Mother
  • 在第 7 行,定義了子類 Child,它繼承於兩個父類:Father 和 Mother

子類繼承所有父類的屬性和方法,從而實現程式碼重用。

4. 多繼承的例子

4.1 概述

本節構造 3 個類:Father、Mother 和 Child,Child 繼承於兩個類 Father 和 Mother,它繼承了這兩個類的屬性和方法,同時有自己特有的屬性和方法,如下圖所示:

4.2 編寫父類 Father

class Father:
    def __init__(self, father_attr):
        self.father_attr = father_attr

    def father_method(self):
        print('father_attr =', self.father_attr)
  • 在第 3 行,定義類 Father 的屬性 father_attr
  • 在第 5 行,定義類 Father 的方法 father_method

4.3 編寫父類 Mother

class Mother:
    def __init__(self, mother_attr):
        self.mother_attr = mother_attr

    def mother_method(self):
        print('mother_attr =', self.mother_attr)
  • 在第 3 行,定義類 Mother 的屬性 mother_attr
  • 在第 5 行,定義類 Mother 的方法 mother_method

4.4 編寫子類 Child

class Child(Father, Mother):
    def __init__(self, father_attr, mother_attr, child_attr):
        Father.__init__(self, father_attr)
        Mother.__init__(self, mother_attr)
        self.child_attr = child_attr

    def child_method(self):
        print('child_attr =', self.child_attr)     
  • 在第 1 行,定義類 Child,繼承於 Father 和 Mother
  • 在第 3 行,呼叫父類 Father 的構造方法
  • 在第 4 行,呼叫父類 Mother 的構造方法
  • 在第 7 行,定義類 Child 的方法 child_method

4.5 建立例項

child = Child('Father', 'Mother', 'Child')        
child.father_method()
child.mother_method()
child.child_method()
  • 在第 1 行,建立例項 Child
  • 在第 2 行,呼叫繼承於父類 Father 的方法 father_method
  • 在第 3 行,呼叫繼承於父類 Mother 的方法 mother_method
  • 在第 4 行,呼叫類自己的方法 child_method

程式輸出結果如下:

father_attr = Father
mother_attr = Mother
child_attr = Child