Python 【類與對象】

類與對象編程

把類的個例就叫作實例 (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)
相關文章
相關標籤/搜索