面向對象
基礎
-
oop
面向對象最重要的概念就是類(Class)和實例(Instance),必須牢記類是抽象的模板,而實例是根據類創建出來的一個個具體的“對象”,每個對象都擁有相同的方法,但各自的數據可能不同。
Python類提供了面向對象編程的所有標準功能:類繼承機制允許多個基類,派生類可以重寫其基類或類的任何方法,並且方法可以調用具有相同名稱的基類的方法。對象可以包含任意數量和種類的數據。與模塊一樣,類也具有Python的動態特性:它們是在運行時創建的,並且可以在創建後進一步修改。 -
定義類
class Employee: '所有員工的基類' # empCount 變量是一個類變量,它的值將在這個類的所有實例之間共享。你可以在內部類或外部類使用 Employee.empCount 訪問。 empCount = 0 # 方法__init__()方法是一種特殊的方法,被稱爲類的構造函數或初始化方法,當創建了這個類的實例時就會調用該方法 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 # self 代表類的實例,self 在定義類的方法時是必須有的,雖然在調用時不必傳入相應的參數。 def displayCount(self): print ("Total Employee %d" % Employee.empCount) print (self.__class__) def displayEmployee(self): print("Name : ", self.name, ", Salary: ", self.salary) ee1= Employee('NICK',100000) ee2= Employee('ROSE',100000) ee1.displayCount() ee2.displayEmployee()
類屬性使用 類名.屬性名 的方式去訪問,對象也可以訪問。但是如果對象修改,則只對當前對象適用(因爲這是其實是增加對象屬性)
-
動態爲對象添加、刪除屬性
只會影響到當前操作的對象
ee1= Employee('NICK',100000) ee2= Employee('ROSE',888888) ee1.age=22 print(ee1.age) # del ee1.name ee1.displayEmployee() # print ee2.age #error print (hasattr(ee1, 'age') ) # 如果存在 'age' 屬性返回 True。 print (getattr(ee1, 'age') ) # 返回 'age' 屬性的值 setattr(ee2, 'age', 8) # 添加屬性 'age' 值爲 8 print(ee2.age) delattr(ee1, 'age') # 刪除屬性 'age'
-
析構函數
def __del__(self): class_name = self.__class__.__name__ print(class_name, "銷燬")
-
內置屬性
print (Employee.__dict__) print (Employee.__doc__) # 類的所有父類構成元素(包含了一個由所有父類組成的元組) print (Employee.__bases__) ee1=Employee('NICK',200) dd2=ee1 dd2.name='dog' # del ee1 # ee1.displayEmployee() dd2.displayEmployee() print(isinstance(ee1,Employee)) print(isinstance(ee1,object))
高級
-
繼承
類的繼承
1:在繼承中基類的構造(init()方法)不會被自動調用,它需要在其派生類的構造中親自專門調用。
2:在調用基類的方法時,需要加上基類的類名前綴,且需要帶上self參數變量。區別在於類中調用普通函數時並不需要帶上self參數
3:Python總是首先查找對應類型的方法,如果它不能在派生類中找到對應的方法,它纔開始到基類中逐個查找。(先在本類中查找調用的方法,找不到纔去基類中找)。
class Boss(Employee): def __init__(self,name,salary,jiangjin): super(Boss, self).__init__(name, salary) self.jiangjin = jiangjin def displayEmployee(self): print("Name : ", self.name, ", Salary: ", self.salary,'other jiangjin:',self.jiangjin)
python沒有重載,因爲函數名知識指向內存地址的變量。
-
多重繼承
#-*- coding:UTF-8 -*- # 多重繼承 class A(object): __scope='a scope' def __init__(self, a): print('init A...') self.a = a def show(self): print('i am A') class B(A): def __init__(self, a): super(B, self).__init__(a) print( 'init B...') def show(self): super(B,self).show() print(' and i am B too') class C(A): def __init__(self, a): super(C, self).__init__(a) print('init C...') def show(self): super(C, self).show() print(' and i am C too too') class D(B, C): def __init__(self, a): super(D, self).__init__(a) print('init D...') def show(self): super(D, self).show() print(' and i am D too too...') d=D(12) # print B.scope d.show() #d多重繼承時爲了從多個類中提取多個方法 # 查看對象信息 # print(isinstance(d,D)) # print(isinstance(d,A)) # # print(type(d)) # print(dir(d))
-
使用接口的思想設計多重繼承
整體可以分爲類型類和功能類兩種類,類型類實現主體繼承樹形結構,功能類作爲獨立的功能接口存在。
#-*- coding:UTF-8 -*- # 多重繼承 class Animal(object): def __init__(self,age): self.age=age # 大類: class Mammal(Animal): def __init__(self,age,foot): super(Mammal,self).__init__(age) self.foot=foot class Bird(Animal): def __init__(self,age,fly): super(Bird,self).__init__(age) self.fly=fly class RunnableMixIn(object): def run(self): print('Running...') class FlyableMixIn(object): def fly(self): print('Flying...') # 各種動物: class Dog(Mammal,RunnableMixIn): def __init__(self,age,foot,gender): super(Dog,self).__init__(age,foot) self.gender=gender def show(self): print('dog age is:',self.age,'ang have ',self.foot) class Bat(Mammal): pass class Parrot(Bird): pass class Ostrich(Bird): pass dog=Dog(3,4,'male') dog.show()