類與對象編程
把類的個例就叫作實例 (instance),可理解爲「實際的例子」
類是某個特定的羣體,實例是羣體中某個具體的個體函數
Python中的對象等於類和實例的集合:即類能夠看做是對象,實例也能夠看做是對象,
好比列表list是個類對象,[1,2]是個實例對象,它們都是對象
「萬事萬物,皆爲對象」性能
類的建立和調用spa
類的建立
類名的首字母要大寫code
1 class Chinese: # 建立一個類 2 eye = 'black' 3 4 def eat(self): #參數self的特殊之處:在定義時不能丟,在調用時要忽略 5 print('吃飯,選擇用筷子。') 6 7 wu = Chinese() # 類的實例化 8 print(wu.eye) # 實例調用類屬性 9 wu.eat() # 調用類中的方法(傳參不用管self)
print(type(wu)) 對象
<class '__main__.Chinese'> #驗證了wufeng屬於Chinese這個類
print(wu)
<__main__.Chinese object at 0x7f295682d400> #Chinese類的一個實例對象(object),後面的一串字符表示這個對象的內存地址blog
#類中建立的屬性和方法能夠被其全部的實例調用,
並且,實例的數目在理論上是無限的。
咱們能夠同時「新建」多個實例繼承
類也被稱爲「實例工廠」,因其爲全部實例提供了一套藍圖(即預先設定好有什麼屬性和方法)內存
建立類的兩個關鍵點
一 。特殊參數:selfci
那麼若是想在類的內部調用類屬性,而實例又還沒建立以前,咱們就須要有個變量先代替實例接收數據,這個變量就是參數self。
1 class Chinese: 2 3 name = '吳' # 類屬性name 4 5 def say(self): 6 print(self.name + '是中國人') 7 8 person = Chinese() # 建立Chinese的實例person 9 person.say() # 調用實例方法
當最後一行代碼運行時,實例person會像參數同樣傳給self,替換掉self,self.name等價於person.name
person.name就至關於調用了類屬性name(即'吳'),而後跑完整個方法
至關於如下:
1 class Chinese: 2 3 name = '吳' # 類屬性name 4 5 def say(person): 6 print(person.name + '是中國人') 7 8 person = Chinese() # 建立Chinese的實例person 9 person.say() # 調用實例方法 10 吳是中國人
若是想在類的方法內部調用其餘方法時,咱們也須要用到self來表明實例
1 class Chinese: 2 3 def greeting(self): 4 print('很高興碰見你') 5 6 def say(self): 7 self.greeting() 8 print('我來自中國') 9 10 person = Chinese() # 建立實例person 11 12 person.say() # 調用say()方法 13 很高興碰見你 14 我來自中國
self表明的是類的實例自己,方便數據的流轉
對此,咱們須要記住兩點
第一點:只要在類中用def建立方法時,就必須把第一個參數位置留給 self,並在調用方法時忽略它(不用給self傳參)。
第二點:當在類的方法內部想調用類屬性或其餘方法時,就要採用self.屬性名或self.方法名的格式。
##############################################################################################
二。特殊方法:初始化方法 (也叫構造函數)
定義初始化方法的格式是def __init__(self),是由init加左右兩邊的【雙】下劃線組成
初始化方法的做用在於:當每一個實例對象建立時,該方法內的代碼無須調用就會自動運行。
1 class Chinese: 2 3 def __init__(self): 4 print('很高興碰見你,我是初始化方法') 5 6 person = Chinese() 7 很高興碰見你,我是初始化方法
編寫習慣上,咱們會在初始化方法內部完成類屬性的建立,爲類屬性設置初始值,
這樣類中的其餘方法就能直接、隨時調用
1 class Chinese: 2 def __init__ (self): 3 self.mouth = 1 # self.不能丟 4 self.eye = 2 5 6 def body(self): 7 print('我有%s張嘴巴' % self.mouth) 8 print('我有%s隻眼睛' % self.eye) 9 10 person = Chinese() 11 person.body() 12 我有1張嘴巴 13 我有2隻眼睛
除了設置固定常量,初始化方法一樣能夠接收其餘參數
1 class Chinese: 2 3 def __init__(self, name, birth, region): 4 self.name = name # self.name = '吳' 5 self.birth = birth # self.birth = '廣東' 6 self.region = region # self.region = '深圳' 7 8 def born(self): 9 print(self.name + '出生在' + self.birth) 10 11 def live(self): 12 print(self.name + '居住在' + self.region) 13 14 person = Chinese('吳','廣東','深圳') # 傳入初始化方法的參數 15 #初始化方法有多個參數的時候,在實例化的時候就要傳入相應的值 16 person.born() 17 person.live() 18 吳出生在廣東 19 吳居住在深圳
#其實還能夠不用初始化方法也能實現
可是此方法比不上初始化方法
初始化優勢:
至少沒必要重複傳參,傳入的數據還能夠被屢次調用
1 class Chinese: 2 3 def born(self, name, birthplace): 4 print(name + '出生在' + birthplace) 5 6 def live(self, name, region): 7 print(name + '居住在' + region) #不建議用此方法 8 9 person = Chinese() 10 person.born('吳','廣東') 11 person.live('吳','深圳')
一次性調用
1 class Chinese: 2 def __init__(self,hometown,region): 3 self.hometown = hometown 4 self.region = region 5 print('程序持續更新中……') 6 7 def born(self): 8 print('我生在%s。'%(self.hometown)) 9 10 def live(self): 11 print('我在%s。'%(self.region)) 12 13 # 新建方法,調用上面的兩個方法(注:方法名可自定義)。 14 def citys(self): 15 self.born() 16 self.live() 17 18 wu = Chinese('廣東', '深圳') 19 wu.citys() 20 # 調用方法後,程序運行方法中的代碼(即依次調用方法`born`和`live`)。 21 程序持續更新中…… 22 我生在廣東。 23 我在深圳。
#####################################################################################################
面向對象編程
與面向對象編程相對應的是面向過程編程
面向過程編程:首先分析出解決問題所須要的步驟(即「第一步作什麼,第二步作什麼,第三步作什麼」),
而後用函數實現各個步驟,再依次調用。
面向對象編程,將代碼具體的數據和處理方法都封裝在類中,讓咱們不用徹底瞭解過程也能夠調用類中的各類方法。
這個優點讓咱們能夠在 Python 中輕鬆地調用各類標準庫、第三方庫和自定義模塊(能夠簡單理解成別人寫好的類)
#類編寫一個直觀的好處就是參數的傳遞會比普通函數要省事不少,也沒必要考慮全局變量和局部變量,由於類中的方法能夠直接調用屬性。
#####################################################################################################################
綜合例子
1 class Robot: 2 def __init__(self): 3 self.name = input('我如今剛誕生,尚未名字,幫我起一個吧。') 4 self.master = input('對了,我要怎麼稱呼你呢?') 5 print('你好%s,我叫%s。很開心,碰見你~'%(self.master,self.name)) 6 7 def say_wish(self): 8 wish = input('告訴我一個你的願望吧:') 9 print(self.master+'的願望是:') 10 # 這裏也能夠用字符串的格式化,不過,用循環語句的話,以後改複述次數會方便些。 11 for i in range(3): 12 print(wish) 13 14 robot1 = Robot() 15 robot1.say_wish()
#############################################################################################################################
類的繼承和定製
A類屬於B類,天然也擁有了B類的全部屬性和方法。
這句話在編程裏就是:A類繼承了B類。
Python中,咱們的習慣表述是:A類是B類的子類,而B類是A類的父類(或超類)
定製
子類也能夠在繼承的基礎上進行個性化的定製
(1)建立新屬性、新方法;
(2)修改繼承到的屬性或方法。
————————————————————————————————————————————
繼承的基礎語法
class Chinese:在運行時至關於class Chinese(object):。
而object,是全部類的父類,咱們將其稱爲根類(可理解爲類的始祖)。
1 #函數isinstance(),判斷某個實例是否屬於某個類 2 print(isinstance(1,int)) ## 判斷1是否爲整數類的實例 3 True 4 print(isinstance(1,str)) 5 False 6 print(isinstance(1,(int,str))) # 判斷實例是否屬於元組裏幾個類中的一個 7 True
1 class Chinese: 2 pass 3 4 class Cantonese(Chinese): 5 pass 6 7 gonger = Chinese() 8 yewen = Cantonese() 9 10 print('\n驗證1:子類建立的實例同時也屬於父類') 11 print(isinstance(gonger,Chinese)) 12 print(isinstance(yewen,Chinese)) 13 14 print('\n驗證2:父類建立的實例不屬於子類。') 15 print(isinstance(gonger,Cantonese)) 16 17 print('\n驗證3:類建立的實例都屬於根類。') 18 print(isinstance(gonger,object)) 19 print(isinstance(yewen,object)) 20 21 驗證1:子類建立的實例同時也屬於父類 22 True 23 True 24 25 驗證2:父類建立的實例不屬於子類。 26 False 27 28 驗證3:類建立的實例都屬於根類。 29 True 30 True
————————————————————————————————————————————
類的繼承之多層繼承
子類建立的實例可調用全部層級父類的屬性和方法
1 class Earthman: 2 eye_number = 2 3 4 # 中國人繼承了地球人 5 class Chinese(Earthman): 6 eye_color = 'black' 7 8 # 廣東人繼承了中國人,同時也繼承了地球人。 9 class Cantonese(Chinese): 10 pass 11 12 yewen = Cantonese() 13 print(yewen.eye_number) 14 print(yewen.eye_color) 15 2 16 black
####################################################################
類的繼承之多重繼承
一個類,能夠同時繼承多個類,
語法爲 class A(B,C,D):
就近原則:
越靠近子類(即越靠左)的父類,越親近,越優先考慮。子類調用屬性和方法時,會先在靠左的父類裏找,找不到才往右找。
1 class Su: 2 born_city = 'Jiangsu' 3 wearing = 'thick' 4 5 def diet(self): 6 print('咱們愛吃甜。') 7 8 class Yue: 9 settle_city = 'Guangdong' 10 wearing = 'thin' 11 12 def diet(self): 13 print('咱們吃得清淡。') 14 15 class Yuesu(Yue,Su): 16 pass 17 18 xiaoming = Yuesu() 19 print(xiaoming.wearing) # 先在 Yue類找,找到了,打印出來。 20 print(xiaoming.born_city) # Yue類沒有born_city,纔去Su類找。 21 xiaoming.diet() # 方法調用,和屬性調用同樣,也符合就近原則。 22 23 thin 24 Jiangsu 25 咱們吃得清淡。
類的定製
定製,能夠新增代碼
1 class Chinese: 2 eye = 'black' 3 4 def eat(self): 5 print('吃飯,選擇用筷子。') 6 7 class Cantonese(Chinese): # 類的繼承 8 native_place = 'guangdong' # 類的定製 9 10 def dialect(self): # 類的定製 11 print('咱們會講廣東話。') 12 13 yewen = Cantonese() 14 print(yewen.eye) # 父類的屬性能用 15 print(yewen.native_place) # 子類的定製屬性也能用 16 yewen.eat() # 父類的方法能用 17 yewen.dialect() # 子類的定製方法也能用 18 19 black 20 guangdong 21 吃飯,選擇用筷子。 22 咱們會講廣東話。
定製,也可重寫代碼
在子類中,對父類代碼的修改
子類繼承父類方法的操做是在def語句後接父類.方法(參數)
1 class Chinese: 2 3 def land_area(self,area): 4 print('咱們居住的地方,陸地面積是%d萬平方千米左右。'% area) 5 6 class Cantonese(Chinese): 7 # 間接對方法進行重寫 8 def land_area(self, area, rate = 0.0188): 9 Chinese.land_area(self, area * rate) 10 # 直接繼承父類方法,再調整參數。 11 12 gonger = Chinese() 13 yewen = Cantonese() 14 gonger.land_area(960) 15 yewen.land_area(960)
提示:初始化方法的定製,和通常的實例方法的定製是同樣的。
1 class Chinese: 2 def __init__(self, greeting='你好', place='中國'): 3 self.greeting = greeting 4 self.place = place 5 6 def greet(self): 7 print('%s!歡迎來到%s。' % (self.greeting, self.place)) 8 9 # 請爲子類完成定製,代碼量:兩行。 10 class Cantonese(Chinese): 11 def __init__(self, greeting='雷猴', place='廣東'): #重寫代碼最好是在繼承方法的基礎上經過代碼的調整完成定製 12 Chinese.__init__(self, greeting ,place) 13 14 yewen = Cantonese() 15 yewen.greet() 16 雷猴!歡迎來到廣東。
###################################################################################################################
列子
1 class Student: 2 def __init__(self, name, job=None, time=0.00, time_effective=0.00): 3 self.name = name 4 self.job = job 5 self.time = time 6 self.time_effective = time_effective 7 8 def count_time(self, hour, rate): 9 self.time += hour 10 self.time_effective += hour * rate 11 12 class Programmer(Student): 13 def __init__(self, name): #此處爲啥只留name參數,由於沒有給出默認值,須要傳入參數,不能省略,而後其餘都是默認參數 14 Student.__init__(self, name, job='programmer', time=0.00, time_effective=0.00) 15 16 def count_time(self, hour, rate=1): 17 Student.count_time(self, hour, rate) 18 19 student1 = Student('韓梅梅') 20 student2 = Programmer('李雷') 21 22 print(student1.job) 23 print(student2.job) 24 25 student1.count_time(10, 0.8) 26 student2.count_time(10) 27 28 print(student1.time_effective) 29 print(student2.time_effective)