面向對象設計包括繼承、多態和封裝
1在python中多態意味着接口,不是函數簽名調用
在有些OOP編程語言中,把多態詮釋為基於函數參數簽名(傳遞參數個數即類型)的重載。由於python中沒有類型聲明,所以函數簽名重載是行不通的,因此,python中的多態是基於對象接口而不是類型。
如下所示,若采用函數簽名是不能實現多態的。應為def會直接把對象賦值給類的作用域中的變量,所以方法函數的最后一次定義才會被保留。換言之,就好像先定義X=1,然后再定義X=2一樣,最后只有X=2保留。

class C: def meth(self,x): print(x,end=' ') def meth(self,x,y): print(x,y,end=' ') X=C() #X.meth(2)#報錯,有一個必要的參數缺失 X.meth(2,3)
2OPP和繼承
在python,從程序員角度來看,繼承是由屬性點號實現,並且由此觸發實例、類以及任何父類中變量名的搜索;從類設計來看,繼承是一種指明集合成員關系的方式:類定義了一個屬性集合,可由更具體的集合(如子類)繼承和定制。

class Employee: def __init__(self,name,salary=0): self.name=name self.salary=salary def giveRaise(self,percent): self.salary=self.salary+(self.salary*percent) def work(self): print(self.name,' does stuff') def __repr__(self): return '<Employee: name=%s,salary=%s>' %(self.name,self.salary) class Chef(Employee): def __init__(self,name): Employee.__init__(self,name,50000) def work(self): print(self.name,'makes food') class Server(Employee): def __init__(self,name): Employee.__init__(self,name,40000) def work(self): print(self.name,'interfaces with customer') class PizzaRobot(Chef): def __init__(self,name): Chef.__init__(self,name) def work(self): print(self.name,'makes pizza') if __name__=='__main__': bob=PizzaRobot('bob') print(bob) bob.work() bob.giveRaise(0.2) print(bob) for klass in Employee,Chef,Server,PizzaRobot: obj=klass(klass.__name__) obj.work()
3.方法是對象
在python中方法也是一種對象,一般用法與其他對象基本相同,可以將他們賦值給變量名、傳遞給函數、存儲在數據結構中等等。由於方法可以通過實例或類來訪問,因此實際上它們在python中有兩種形式:
未綁定(類)方法對象:無self
通過對類進行點號運算從而獲取類的函數屬性,會傳回為綁定方法對象。調用該方法時,必須明確提供實例對象作為第一個參數。
綁定方法對象:self+函數
通過實例對象進行點號運算從而獲取類的函數屬性,會傳回綁定方法對象。python在綁定方法對象中自動把實例和函數打包,所以不需要傳遞實例調用該方法。

class Spam: def doit(self,message): print(message) obj=Spam() obj.doit('hello1') #通過實例調用 Spam.doit(obj,'hello2') #通過類調用方法