面向對象程序設計最主要的有三個特徵:封裝、繼承、多態
本節內容主要講解面向對象的第一個特徵:繼承
1 繼承的意義
繼承是讓我們抽象的對象之間存在一定的所屬關係
在繼承關係中,我們一定要明確會出現這樣的一種關係~父類、子類,子類繼承自父類,可以繼承父類中的公開的屬性和方法(不能繼承私有的屬性或者方法)
其實我們在前面定義對象的時候已經使用過了繼承,python中所有的對象都是直接或者間接繼承自object對象的
class Person(object):
pass
上述代碼中,我們定義了一個類型Person,這個Person後面有一個括號,括號中就是繼承的類型;python中繼承的語法是
class 類型名稱(父類名稱):
pass
下面是一個簡單的繼承的案例
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 定義一個人的類型
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
class Person(object):
def __init__(self, name, age, gender):
self.__name = name
self.__age = age
self.__gender = gender
# 定義get獲取屬性的方法
def get_name(self):
return self.__name
def get_age(self):
return self.__age
def get_gender(self):
return self.__gender
# 定義set設置屬性的方法
def set_name(self, name):
self.__name = name
def set_age(self, age):
self.__age= age
def set_gender(self, gender):
self.__gender= gender
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 定義一個男人的類型,繼承自Person類型
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
class Man(Person):
def __init__(self, name, age):
Person.__init__(self, name, age, "男")
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 定義一個女人的類型,繼承自Person類型
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
class Women(Person):
def __init__(self, name, age):
Person.__init__(self, name, age, "女")
# 創建男人對象和女人對象,測試是否可以給屬性進行賦值取值
m = Man("tom", 18)
w = Women("jerry", 16)
print(m.get_gender()) # 執行結果:男
print(w.get_gender()) # 執行結果:女
我們可以看到,在自定義類Man和Women中,只是簡單定義了一個init方法,沒有其他的代碼,但是我們創建的Man類型的對象和Women類型的對象,卻可以使用父類Person中定義的方法get_gender()以及其他,在一定程度上,簡化了我們的開發,同時提高了程序的擴展性
繼承:就是將一部分表示數據類型相似的類,抽取他們共同的屬性和方法單獨封裝成父類,讓這些類繼承這個父類,實現代碼的複用的同時提高程序的擴展性。
2. 繼承中類型的關係
-
繼承是類型之間的關係:繼承中,首先必須是兩個或者兩個以上的類型之間的關係,注意是類型之間的關係
-
繼承中的父類和子類:被繼承的稱爲父類,實現繼承的稱爲子類,子類繼承自父類,實現的是一種A is a B的關係
如:貓是一種類型,繼承自動物這種類型,反映出來的是貓這種類型可以具備動物具備的屬性和行爲,同時貓是一種動物。(切記,A繼承B反映的是A is a B的關係,不能反過來,貓是一種動物,不能說動物是貓)
- 多繼承機制:一個父類可以有多個子類,一個子類同樣也可以有多個父類
某些情況下,我們生活中會出現這樣的情況,一個小孩既是父親的兒子,要具備兒子應該具備的功能,同時也是一個學生要具備學生應該具備的功能,此時就需要使用Python中的多繼承來實現了# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # 定義一個人的類型,男人是人,女人也是人 # 一個父類,多個子類 # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # 父類 class Person(object): pass # 子類 class Man(Person): pass # 子類 class Women(Person): pass
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # 定義一個兒子的類型~要孝順 # 定義一個學生的類型~要好好學習天天向上 # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * class Son(object): def fealty(self): print("孝順父母") class Student(object): def study(self): print("好好學習,天天向上") # 定義子類,繼承兒子類型和學生類型 class Person(Son, Student): pass # 創建對象,使用父類的方法 p = Person() p.fealty() p.study() # 執行結果 ~ 孝順父母 ~ 好好學習,天天向上
- 數據繼承和訪問,在python的繼承機制中,私有的屬性是不允許被繼承和互相訪問的,子類不能繼承和訪問父類中私有的屬性和方法,父類同樣也不能訪問子類中私有的屬性和方法
子類只能繼承父類中公開的屬性和方法
子類中可以通過父類的名稱或者super()來訪問父類的屬性和方法# 父類 class Person(object): def __init__(self, name, age): self.__name = name self.__age = age def play(self): print(self.__name + "在玩遊戲") # 子類 class Man(Person): def __init__(self, name, age): # 通過父類名稱訪問父類中初始化的方法 Person.__init__(self, name,age) # 子類 class Women(Person): def __init__(self, name, age): # 通過super()訪問父類初始化的方法 # super(Women, self).__init....super中的參數可以省略 super().__init__(self, name, age)
3. 繼承時的方法重寫(方法覆蓋)
在子類繼承自父類之後,可以直接使用父類中定義的公開的方法進行操作
# 父類
class Person(object):
def play(self):
print("Person中玩遊戲的方法執行了...")
# 子類
class Children(Person):
pass
# 創建子類對象
c = Children()
c.play()
# 執行結果
~Person中玩遊戲的方法執行了...
在子類中,我們可以重新編寫繼承自父類的方法
# 父類
class Person(object):
def play(self):
print("Person中玩遊戲的方法執行了...")
# 子類
class Children(Person):
# 重寫父類中play方法
def play(self):
print("Children中玩遊戲的方法執行.....")
# 創建子類對象
c = Children()
c.play()
# 執行結果
~Children中玩遊戲的方法執行.....
在繼承關係下,在子類中將繼承自父類的方法進行重新定義的過程,稱爲方法重寫或者方法覆蓋,經過重寫或者覆蓋的方法,子類執行該方法時,執行的就是重寫過的方法。