標籤:訪問 結果 機制 多態性 pre 動態類型 執行個體 soft self
本文主要通過幾個執行個體介紹Python物件導向編程中的封裝、繼承、多態三大特性。
封裝性
我們還是繼續來看下上文中的例子,使用Student類建立一個對象,並修改對象的屬性。代碼如下:
#-*- coding:utf-8 -*-#類的建立class Student(object): def __init__(self, name, age): self.name = name self.age = age if __name__ == ‘__main__‘: stu1 = Student(‘Zhangsan‘, 18) stu1.age = -1 print stu1.age
執行個體中將Stu1對象的age屬性值成功修改為-1,這在程式中沒有問題。但在現實生活中是不合理的。因此,在進行Student類設計時,需要對age、name屬性做一些訪問限定,不允許外界隨便訪問。這就需要實作類別的封裝。
所謂類的封裝是指在定義一個類時,將類中的屬性私人化,私人屬性只能再它所在類中被訪問。為了能讓外界訪問私人屬性,可以設定公用介面去擷取或者修改屬性值。我們通過修改代碼,實現Student類的封裝。修改後代碼如下:
#-*- coding:utf-8 -*-#類的建立class Student(object): def __init__(self): self.__name = "" self.__age = 0 def setName(self, name): self.__name = name def setAge(self, age): if (age > 0): self.__age = age else: print "input age invalid" def getName(self): return self.__name def getAge(self): return self.__age if __name__ == ‘__main__‘: stu1 = Student() stu1.setName("Zhangsan") stu1.setAge(-1) print "stu1.getName() = %s" % (stu1.getName(),) print "stu1.getAge() = %d" % (stu1.getAge(),)
代碼說明:
(1)name、age定義有執行個體私人屬性。Python沒有類似Java中的private、procoted、public的修飾符去區分執行個體私人屬性和執行個體公有屬性。而是通過在屬性的名字前以是否存在兩個底線開始為標誌,如果存在雙下劃綫就表示為私人屬性。反之,則表示公有屬性。
(2)setName()、setAge()方法用於設定屬性的值,可以在函數裡增加邏輯對輸入的參數進行判斷。getName()、getAge()方法作為外部介面,用於擷取屬性的值。實現了對屬性操作的封裝。
繼承性
繼承是物件導向的重要特性之一。通過繼承可以建立新類,目的是使用或修改現有類的行為。原始的類稱為父類或超類,新類稱為子類或衍生類別。繼承可以實現代碼的重用。Python在類名後使用一對括弧表示繼承的關係,括弧中的類即為父類。如果父類定義了__init__方法,子類必須顯示調用父類的__init__方法。如果子類需要擴充父類的行為,可以添加__init__方法的參數。下面這段代碼示範了繼承的實現。
#-*- coding:utf-8 -*-#類的建立class Fruit(object): def __init__(self, color): #__init__為類的建構函式 self.color = color #執行個體屬性 print "Fruit‘s color = %s " % (self.color,) def grow(self): print "Fruit grow()"class Apple(Fruit): #繼承自Fruit類 def __init__(self, color, name): #子類的建構函式 Fruit.__init__(self, color) #顯式調用父類的建構函式 print "Apple‘s color = %s " % (self.color,) self.name = name #新增屬性 def sale(self): print "Apple sale()" # 改寫父類中的grow方法class Banana(Fruit): #繼承自Fruit類 def __init__(self, color): #子類的建構函式 Fruit.__init__(self, color) #顯式調用父類的建構函式 def grow(self): #新增方法 print "Banana grow()" if __name__ == ‘__main__‘: apple = Apple(‘red‘, ‘apple‘) # apple.grow() #繼承父類的grow方法,可以直接調用 apple.sale() banana = Banana(‘yellow‘) banana.grow() #
例子中Apple類通過繼承Fruit類,自動擁有了color屬性和grow()方法。通過繼承的方式,可以減少代碼的重複編寫。
多態性
繼承機制說明子類具有父類的公有屬性和方法,而且子類可以擴充自身的功能,添加新的屬性和方法。因此,子類可以替代父類對象,這種特性稱為多態性。由於Python的動態類型,決定了Python的多態性。下面看吧這一段代碼。
#-*- coding:utf-8 -*-#類的建立class Fruit(object): def __init__(self, color=None): #__init__為類的建構函式 self.color = color #執行個體屬性 class Apple(Fruit): #繼承自Fruit類 def __init__(self, color=‘red‘): #子類的建構函式 Fruit.__init__(self, color) #顯式調用父類的建構函式class Banana(Fruit): #繼承自Fruit類 def __init__(self, color=‘yellow‘): #子類的建構函式 Fruit.__init__(self, color) #顯式調用父類的建構函式 class Fruitshop(object): def sellFruit(self, fruit): if isinstance(fruit, Apple): print "sell apple" if isinstance(fruit, Banana): print "sell apple" if isinstance(fruit, Fruit): print "sell Fruit" if __name__ == ‘__main__‘: shop = Fruitshop() apple = Apple() banana = Banana() shop.sellFruit(apple) shop.sellFruit(banana)
輸出結果如下:
sell applesell Fruitsell applesell Fruit
在Fruitshop類中定義了sellFruit()方法,該方法提供參數fruit。sellFruit()根據不同的水果類型返回不同的結果。實現了一種調用方式不同的執行結果。這就是多態。利用多態性,可以增加程式的靈活性和可擴充性。
Python物件導向編程(下)