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 方法。
“你們紀念的只是過去,如果拉上你的各種同學到你面前,你們還是無話可說。”