python面向物件--類/函式/繼承
面向物件與面向過程
python是一門面向物件的程式語言,面向物件是一種程式設計思想,與之相對應的是面向過程。
1、面向過程
面向過程其實就是把過程當做設計核心,根據問題的發展順序,依次解決問題,儘可能的把過程中涉及到的問題完善解決。他有他的優點,當拿到一個問題時,可以方便的按執行的步驟寫程式碼,但是當邏輯關係變得複雜時,有一個地方出現差錯就會導致整個程式無從下手。面向物件的程式語言還是很多的,例如C++、Java等等。
優點是:極大的降低了寫程式的複雜度,只需要順著要執行的步驟,堆疊程式碼即可。
缺點是:一套流水線或者流程就是用來解決一個問題,程式碼牽一髮而動全身。
應用場景:一旦完成基本很少改變的場景,著名的例子有Linux核心,git,以及Apache HTTP Server等。
2、面向物件
面向物件程式設計把計算機程式的執行看做一組物件的集合,每個物件之間進行訊息的傳送處理。有一個顯著的優點就是,對某個物件進行修改,整個程式不會受到影響,自定義資料型別就是面向物件中的類的概念,而我們需要把他們的介面處理好就可以。
優點是:解決了程式的擴充套件性。對某一個物件單獨修改,會立刻反映到整個體系中,如對遊戲中一個人物引數的特徵和技能修改都很容易。
缺點:可控性差,無法向面向過程的程式設計流水線式的可以很精準的預測問題的處理流程與結果,面向物件的程式一旦開始就由物件之間的互動解決問題
應用場景:需求經常變化的軟體,一般需求的變化都集中在使用者層,網際網路應用,企業內部軟體,遊戲等都是面向物件的程式設計大顯身手的好地方。
類與物件
1、類:用來描述具有相同的屬性和方法的物件的集合。它定義了該集合中每個物件所共有的屬性和方法。即類是一個種類,一個模型。
2、物件(例項):類的例項。即根據模型製造出來的具體某個東西
3、例項化:從類到物件的過程。即從模型到成品東西的過程。
4、方法:類裡面的函式
5、屬性:類裡面的變數就為類的屬性。類有兩種屬性:靜態屬性和動態屬性
6、類的定義和使用實際操作:
self:代表的本類物件。在類中,代表本類物件;在類外,需要用具體的例項名代替self。My.say(m) 等同於m.say()
cls:在類中,代表本類;在類外,需要用具體的類名代替cls。
類變數:就在直接在類下面定義的變數,沒有加self的,每個例項都可以用
class Car: #定義類 wheel =4 #類變數,公共的,呼叫的時候沒有時,從公共變數中找。防止每個例項都定義的時候浪費記憶體 def __init__(self,color,brand): #self.wheel=wheel self.color = color #例項變數 self.brand = brand def help(self): #類中的方法 print('汽車有%s個輪子'%self.wheel) print('汽車的顏色是%s'%self.color) print('='*10) my = Car('赤橙黃綠青藍紫','我的') #類例項化 my.help()
類的函式
1、建構函式:類在例項化的時候會自動執行的一個函式
- 定義格式:
class 類名: def __init__(self,引數-若有):
- 呼叫:
#類外呼叫如下: 物件名=類名(引數-若有) # 1、建立例項物件並自動呼叫建構函式。 類名.__init__(物件名,引數-若有) # 2、已建立物件例項的前提下,執行建構函式。 物件名.__init__(引數-若有) # 3、例項.方法查詢順序:例項方法→類方法
2、解構函式:例項在銷燬的時候自動執行的函式。一般關閉資料庫連線、關閉檔案等操作可以寫在解構函式。
- 定義格式:
class 類名: def __del__(self):
- 呼叫:
# 類外呼叫如下 : # 1、無顯式銷燬例項時,則當程式執行結束後,自動銷燬例項,自動呼叫解構函式 del 物件名 # 2、顯式銷燬例項後,則立即自動呼叫解構函式 類名.__del__(物件名) # 3、直接呼叫解構函式。並沒有銷燬例項。
3、類方法:@classmethod標識
- 不需要例項化就可以呼叫
- 它可以使用類變數
- 呼叫其他的類方法。
- 它不可以使用例項方法、例項變數
- 如果類裡面的這個方法,它並沒有使用到其他的例項變數、或者其他例項方法,那麼就給他定義成類方法
定義格式:
class 類名: @classmethod def 方法名(cls,引數-若有):
呼叫:
#類內、類外呼叫如下: 類名.類方法(引數-若有) #類外呼叫如下: 物件名.類方法(引數-若有) # 例項.方法查詢順序:例項方法→類方法 #類內呼叫如下: class 類名: @classmethod def 方法名(cls,引數-若有): cls.類方法(引數-若有) class 類名: def 方法名(self,引數-若有): self.類方法(引數-若有) # 方法名指所有能傳self的方法。 # self.方法查詢順序:例項方法→類方法
class Car: wheel = 4 #類變數 def __init__(self,color,p): self.color = color #例項變數 self.p = p def help(self): print('汽車有%s個輪子'%self.wheel) print('汽車的顏色是%s'%self.color) print('牌子%s'%self.p) print('='*10) #self.haha() self.check_wheel() @classmethod #類方法 def check_wheel(cls): print('cls的記憶體地址',id(cls)) print(cls.wheel) Car.check_wheel()
4、靜態方法:@staticmethod 標識
- 不需要例項化就可以呼叫的
- 它就是一個定義在類裡面的普通函式,不能使用例項變數、例項方法、不能使用類變數、類方法。
- 可以用靜態方法呼叫另一個靜態方法,如果改用類方法呼叫靜態方法,可以讓cls代替類,讓程式碼看起來精簡一些。也防止類名修改了,不用在類定義中修改原來的類名。
- 定義格式:
class 類名: @staticmethod def 方法名(引數-若有):
- 呼叫:
#類外呼叫如下: 物件名.靜態方法 # 注意末尾沒有括號 #類內呼叫如下: class 類名: @classmethod def 方法名(cls,引數-若有): cls.靜態方法(引數-若有) class 類名: def 方法名(self,引數-若有): self.靜態方法(引數-若有) # 方法名指所有能傳self的方法。
class Car: wheel = 4 #類變數 def __init__(self,color,p): self.color = color #例項變數 self.p = p @staticmethod #靜態方法,誰都可以呼叫 def help2(): print('這個類的作用是造汽車,它裡面有xxx方法') Car.help2()
5、屬性方法:@property 標識
適用於需要獲取方法返回值,而且沒有入參時使用。
看起來像變數的一個函式。
1、例項方法
2、呼叫不能有入參
3、用它的時候,直接m.func,把它當做一個變數用就ok了,不需要加括號呼叫
4、它是獲取函式的返回值
- 定義格式:
class 類名: @property def 方法名(self,引數-若有):
- 呼叫:
#類外呼叫如下: 物件名.屬性方法 # 注意末尾沒有括號 #類內呼叫如下: class 類名: def 方法名(self,引數-若有): print(self.屬性方法) # 方法名指所有能傳self的方法。
class Car: wheel = 4 #類變數 def __init__(self,color,p): self.color = color #例項變數 self.p = p @staticmethod #靜態方法,誰都可以呼叫 def help2(): print('這個類的作用是造汽車,它裡面有xxx方法') @property #屬性方法 def yesterday(self): #昨天 import datetime res = datetime.date.today() + datetime.timedelta(-1) return str(res) Car.help2() my = Car('赤橙黃綠青藍紫','我的') print(my.yesterday)#注意沒有括號
6、例項方法:正常定義的類裡的self函式都是例項方法,必須得例項化之後才可以使用。
- 定義格式:
class 類名: def 方法名(self,引數-若有):
- 呼叫:
#類外呼叫如下: 物件名.例項方法(引數-若有) #類內呼叫如下: class 類名: def 方法名(self,引數-若有): self.例項方法(引數-若有) # 方法名指所有能傳self的方法。
class Car: wheel = 4 #類變數 def __init__(self,color,p): self.color = color #例項變數 self.p = p def help(self): print('汽車有%s個輪子'%self.wheel) print('汽車的顏色是%s'%self.color) print('牌子%s'%self.p) print('='*10) self.haha() self.check_wheel() @classmethod def check_wheel(cls): print('cls的記憶體地址',id(cls)) print(cls.wheel) cls.haha() @classmethod def haha(cls): print('哈哈哈') cls.help2() @staticmethod def help2(): print('這個類的作用是造汽車,它裡面有xxx方法')
7、私有方法:私有方法只能在類裡面呼叫 ,不能在類外呼叫,子類也不可以呼叫。比如說連線資料庫client。私有變數也一樣,只能在類中使用
- 定義格式:
class 類名: #第一種 @classmethod def __方法名(cls,引數-若有):4 class 類名: #第二種 def __方法名(self,引數-若有):
- 呼叫:
#類內呼叫如下: class 類名: #第一種 @classmethod def 方法名(cls,引數-若有): cls.私有方法(引數-若有) class 類名: #第二種 def 方法名(self,引數-若有): self.私有方法(引數-若有) # 方法名指所有能傳self的方法。
class My: def test(self): self.__password=123456#私有變數,在類中可以用,出了類就不能使用 def say(self): self.__password=7890 def update(self): self.__set_password()
m= My()
m.test()
m.say()
m.update() #類外面不能使用,則報錯
變數
1、例項變數
什麼時候用到例項變數?如一個變數值在本類的多個函式中都要用到的,可以宣告為例項變數。如連線資料庫使用頻繁,為了避免每次處理資料都要連線一次,可以將連線資料庫放在建構函式中。當然這個也可以放在例項方法中,具體看應用的頻繁程度。
- 定義格式:
class 類名: def 方法名(self,引數-若有): self.變數名 = 變數值 # 方法名指所有能傳self的方法。 類方法、靜態方法中不能定義例項變數。
- 呼叫:
如下: 物件名.例項變數 #第一種 #類內呼叫如下: self.例項變數 #第一種
2、私有變數
私有變數只能在類裡面呼叫 ,不能在類外呼叫,子類也不可以呼叫。比如說連線資料庫client不想在類外被修改,所以使用私有變數__client就不會被修改到。私有變數會比較安全。
- 定義格式:
class 類名: #第一種 def 方法名(self,引數-若有): self.__變數名 = 變數值 # 方法名指所有能傳self的方法。 class 類名: #第二種 @classmethod def 方法名(cls,引數-若有): cls.__變數名 = 變數值 # 方法名指類方法。
- 呼叫:
#類內呼叫如下: self.__私有變數 #第一種 # 私有變數查詢順序:非類私有變數->類私有變數 cls.__私有變數 #第二種:類私有變數
3、區域性變數
- 定義格式:
class 類名: def 方法名(self/cls-若有,引數-若有): 變數名 = 變數值 # 方法名指所有方法。
- 呼叫
1 #本函式內呼叫如下: 2 區域性變數名
4、全域性變數
- 定義格式:
class 類名: def 方法名(self/cls-若有,引數-若有): global 變數名 變數名 = 變數值 # 方法名指所有方法。
- 呼叫:
1 #全域性變數定義至程式結束作用域內呼叫如下: 2 全域性變數名
面向物件特性--繼承
繼承是一種建立新類的方式,在python中,新建的類可以繼承一個或多個父類,父類又可稱為基類或超類,新建的類稱為派生類或子類
class ParentClass1: #定義父類 pass class ParentClass2: #定義父類 pass class SubClass1(ParentClass1): #單繼承,基類是ParentClass1,派生類是SubClass pass class SubClass2(ParentClass1,ParentClass2): #python支援多繼承,用逗號分隔開多個繼承的類 pass
class Lm: money=1000000 house = 5 def driver(self): print('開車') class Mcb(Lm):#繼承了父類,父類中有的他都有 def about_me(self): print('我有%s錢,%s房子'%(self.money,self.house)) self.driver() def driver(self): #子類有的時候,就不會繼承父類的方法 print('dddddd開車') print(Mcb.money) m=Mcb() m.about_me()
更多參考:
http://www.cnblogs.com/Eva-J/articles/7293890.html
https://www.cnblogs.com/benric/p/5064169.html