天天看點

Python學習手冊之類和繼承

在上一篇文章中,我們介紹了 Python 的函數式程式設計,現在我們介紹 Python 的類和繼承。

檢視上一篇文章請點選:https://www.cnblogs.com/dustman/p/10010690.html

先前,我們研究過兩種程式設計範式--指令式(使用語句、循環和函數)和函數(使用純函數、高階函數和遞歸)。

接下來我們學習一個程式設計方式是面向對象程式設計 —— Object Oriented Programming,簡稱 OOP,這是一種程式設計思想。OOP 把對象作為程式的基本單元,類描述對象将是什麼,一個對象包含了資料和操作資料的函數。

面向過程的程式設計把計算機程式視為一系列的指令集合,即一組函數的順序執行為了簡化程式設計,面向過程把函數繼續切分為子函數,即把大塊函數通過切割成小塊函數來降低系統的複雜度。

而面向對象的程式設計把計算機程式視為一組對象的集合,而每個對象都可以接收其他對象發過來的消息并處理這些消息。計算機程式的執行就是一系列消息在各個對象之間傳遞。

類是使用關鍵字 class 和縮進塊建立的,縮進塊包含類方法(這些是函數)。

class Dog:
 def __init__(self,name): #__init__傳參數
  self.name = name

d1 = Dog("張三")
d2 = Dog("李四")
d3 = Dog("王五")           

複制

資料封裝、繼承和多态是面向對象的三大特點。           

複制

__init__方法

__init__方法是類中比較重要的方法,它在建立類的執行個體(對象)時調用,這種方法建立的屬性我們稱為執行個體變量。

類中所有方法都必須将 self 作為它們的第一個參數,盡管它沒有顯式傳遞,但是 Python 将 self 參數添加到清單中。在調用方法時不需要包含它。在方法定義中,self 引用調用該方法的執行個體。類的執行個體具有屬性,這些屬性是與執行個體關聯的資料。

在本例中,Dog 執行個體将具有 name 和 eyes 的屬性。可以通過執行個體後面加點和屬性名來通路這些值。同樣,在 __init__ 方法中,可以使用 self.attribute 來設定執行個體屬性的初始值。

class Dog:
 def __init__(self,name,eyes): #__init__傳參數
  self.name = name
  self.eyes = eyes

d1 = Dog("張三",2)
d2 = Dog("李四",2)
d3 = Dog("王五",2)
print(d1.name)
print(d2.name)
print(d3.name)           

複制

特殊方法 __init__ 前後分别有兩個下劃線!
在上面的執行個體中,__init__ 方法接受兩個參數,并将它們配置設定給對象的屬性。__init__ 方法稱為類構造函數。           

複制

方法

類可以定義其他方法用來添加一些功能。請記住,所有方法都必須将 self 作為它們的第一個參數。使用點加屬性的文法來通路這些方法。

class Dog:
 def __init__(self,name,eyes): #__init__傳參數
  self.name = name
  self.eyes = eyes

 def bulk(self):
  print("%s:wang wang wang!" %self.name)

d1 = Dog("張三",2)
d2 = Dog("李四",2)
d3 = Dog("王五",2)

d1.bulk()
d2.bulk()
d3.bulk()           

複制

運作結果:

>>>
張三:wang wang wang!
李四:wang wang wang!
王五:wang wang wang!
>>>           

複制

類屬性一種是通過 __init__ 方法來定義,也可以自己直接定義類屬性,這種屬性我們叫它類變量。它是通過在類的主體内配置設定變量建立的。可以從類的執行個體或類本身通路它們。

class Dog:
 def __init__(self,name,eyes): #__init__傳參數
  self.name = name
  self.eyes = eyes

d1 = Dog("張三",2)
d2 = Dog("李四",2)
d3 = Dog("王五",2)

print(d1.name)
print(d2.name,d2.eyes)
print(d3.eyes)           

複制

運作結果:

>>>
張三
李四 2
2
>>>           

複制

類變量由類的所有執行個體共享。           

複制

嘗試通路一個執行個體中未定義的屬性或方法會導緻 AttributeError 異常。

class Student:
 def __init__(self,id,name):
  self.id = id
  self.name = name

man = Student(10086,"China")
print(man.id)
print(man.sex)           

複制

運作結果:

>>>
10086
AttributeError: 'Student' object has no attribute 'sex'
>>>           

複制

繼承

通過在兩個類中共享函數實作繼承。

想像以下有些類,比如 Cat, Dog, Rabbit。盡管它們有一些不同,但是它們都有顔色,名字屬性。

這些相同點可以通過繼承父類 Animal 來實作這些共享的屬性方法。繼承最大的好處是子類獲得了父類的全部功能。

class Animal:
 def __init__(self,name,sex):
  self.name = name
  self.sex = sex

class Cat(Animal):
 def talk(self):
  print('Neow!')

func = Cat("ZS","F")
print(func.name)
func.talk()           

複制

運作結果:

>>>
ZS
Neow!
>>>           

複制

在 OOP 程式設計中,當我們定義了一個 class 的時候,可以從某個現有的 class 繼承,新的 class 稱為子類 (Subclass) , 而被繼承的 class 稱為基類、父類或超類 (Base class、Super class)。

如果一個子類擁有一個和父類相同的屬性和方法,我們稱為重寫 (override)。在代碼運作的時候,總是會調用子類的方法。

class Animal:
 def __init__(self,name,sex):
  self.name = name
  self.sex = sex

 def take(self):
  print("Hello...")

class Cat(Animal):
 def talk(self):
  print('Neow!')

func = Cat("ZS","F")
print(func.name)
func.talk()           

複制

運作結果:

>>>
ZS
Neow!
>>>           

複制

上面例子中 Animal 是父類,Cat 是子類。           

複制

子類同樣可以做為父類被繼承,這樣繼承的子類擁有兩個父類的方法和屬性。

class A:
 def func_A(self):
  print("A 類")

class B(A):
 def func_B(self):
  print("B 類")

class C(B):
 def func_C(self):
  print("C 類")

obj = C()
obj.func_A()
obj.func_B()
obj.func_C()           

複制

運作結果:

>>>
A 類
B 類
C 類
>>>           

複制

注意:盡量不要循環繼承。           

複制

方法 super 用來在子類中代指父類,可以用于在執行個體的父類中找到具有特定名稱的方法。

class Animal:
 def msg(self):
  print("It's a dog!")

class Cat(Animal):
 def talk(self):
  print('Neow!')
  super().msg()

Cat().msg()           

複制

運作結果:

>>>
It's a dog!
>>>           

複制

Cat().msg() 調用父類的 msg 方法。           

複制

“你們紀念的隻是過去,如果拉上你的各種同學到你面前,你們還是無話可說。”