Python面向對象編程(二)
在前面一篇文章中談到了類的基本定義和使用方法,這只體現了面向對象編程的三大特點之一:封裝。下面就來了解一下另外兩大特征:繼承和多態。
在Python中,如果需要的話,可以讓一個類去繼承一個類,被繼承的類稱為父類或者超類、也可以稱作基類,繼承的類稱為子類。並且Python支持多繼承,能夠讓一個子類有多個父類。
一.繼承和多繼承
在Python中類的繼承定義基本形式如下:
#父類 class superClassName: block #子類 class subClassName(superClassName): block
在定義一個類的時候,可以在類名后面緊跟一對括號,在括號中指定所繼承的父類,如果有多個父類,多個父類名之間用逗號隔開。以大學里的學生和老師舉例,可以定義一個父類UniversityMember,然后類Student和類Teacher分別繼承類UniversityMember:
class UniversityMember: def __init__(self,name,age): self.name = name self.age = age def getName(self): return self.name def getAge(self): return self.age class Student(UniversityMember): def __init__(self,name,age,sno,mark): UniversityMember.__init__(self,name,age) #注意要顯示調用父類構造方法,並傳遞參數self self.sno = sno self.mark = mark def getSno(self): return self.sno def getMark(self): return self.mark class Teacher(UniversityMember): def __init__(self,name,age,tno,salary): UniversityMember.__init__(self,name,age) self.tno = tno self.salary = salary def getTno(self): return self.tno def getSalary(self): return self.salary
在大學中的每個成員都有姓名和年齡,而學生有學號和分數這2個屬性,老師有教工號和工資這2個屬性,從上面的代碼中可以看到:
1)在Python中,如果父類和子類都重新定義了構造方法__init( )__,在進行子類實例化的時候,子類的構造方法不會自動調用父類的構造方法,必須在子類中顯示調用。
2)如果需要在子類中調用父類的方法,需要以 父類名.方法 這種方式調用,以這種方式調用的時候,注意要傳遞self參數過去。
對於繼承關系,子類繼承了父類所有的公有屬性和方法,可以在子類中通過父類名來調用,而對於私有的屬性和方法,子類是不進行繼承的,因此在子類中是無法通過父類名來訪問的。
對於多重繼承,比如
class SubClass(SuperClass1,SuperClass2)
此時有一個問題就是如果SubClass沒有重新定義構造方法,它會自動調用哪個父類的構造方法?這里記住一點:以第一個父類為中心。如果SubClass重新定義了構造方法,需要顯示去調用父類的構造方法,此時調用哪個父類的構造方法由你自己決定;若SubClass沒有重新定義構造方法,則只會執行第一個父類的構造方法。並且若SuperClass1和SuperClass2中有同名的方法,通過子類的實例化對象去調用該方法時調用的是第一個父類中的方法。
二.多態
多態即多種形態,在運行時確定其狀態,在編譯階段無法確定其類型,這就是多態。Python中的多態和Java以及C++中的多態有點不同,Python中的變量是弱類型的,在定義時不用指明其類型,它會根據需要在運行時確定變量的類型(個人覺得這也是多態的一種體現),並且Python本身是一種解釋性語言,不進行預編譯,因此它就只在運行時確定其狀態,故也有人說Python是一種多態語言。在Python中很多地方都可以體現多態的特性,比如 內置函數len(object),len函數不僅可以計算字符串的長度,還可以計算列表、元組等對象中的數據個數,這里在運行時通過參數類型確定其具體的計算過程,正是多態的一種體現。有些朋友提出Python不支持多態,我是完全不贊同的,比如這篇博客《Python中的多態》中提到的:
這種看法過於片面,Java以及C++是編譯性語言,它們體現多態這種特性的方式和Python不同,所以不能只憑Java和C++中那種思維來理解Python中的多態,Python以它這種獨有的方式體現多態的根本原因我覺得有兩點:1)Python是解釋性語言;2)Python中變量是弱類型的。所以Python體現多態的方式和Java決然不同,但是不能因為同Java中體現多態的方式不同就認為Python不支持多態,這種想法過於片面。
關於Python面向對象編程暫時就講解這么多了,至於如何設計類讓它更符合軟件工程的范疇和原則,這個暫時不在討論范圍之內,有興趣的朋友可以看一下《大話設計模式》以及《Head First設計模式》這些書籍。