面向物件的自我總結
阿新 • • 發佈:2018-11-07
面向過程是一種以過程為中心的程式設計思想。
面向物件程式設計主要針對大型軟體設計提出的,次程式設計方式的實現是基於對類和物件的使用。
總結3大特點:封裝,繼承,多型
class Car(): def __init__(self,pp="寶馬",ys="紅色",jg="35W"):#類中的構造方法 self.pp=pp #__init__()為建構函式,在建立一個物件時被呼叫,第一個引數是self self.ys=ys #例項屬性 self.jg=jg def jia_shi(self): #公有方法 print("我正駕駛一輛%s色的%s車"%(self.ys,self.pp)) def setter_name(self,n): #呼叫該方法可以重置該值 self.pp = n def getter(self): #呼叫該方法可以獲取該值 return self.pp def __str__(self): #該方法是魔法方法,可以返回這個物件包含的資訊 return '你的%s愛車要定期保養'%self.pp def __del__(self): print('我已被刪除') #該方法為析構方法,每次建立物件後Python直譯器預設呼叫該方法,無需手動呼叫 car1=Car("奔弛","黑色","40W") #例項化物件 car1.jia_shi() #例項物件呼叫例項方法 #我正駕駛一輛黑色色的奔弛車 print(car1.pp) #例項物件呼叫例項屬性 #奔弛 print(car1) #呼叫__str__方法返回字串 #你的奔弛愛車要定期保養 def car1 #刪除物件後無法再呼叫該物件
總結:例項方法,屬性只能被被例項物件呼叫,類無法呼叫!這些方法也叫做公有方法。
私有方法
def jia_shi(self): #公有方法
self.__woshijingtai()#私有方法只能在類中通過self呼叫,物件無法呼叫
def __woshijingtai(self): #私有方法以雙下劃線開始
__n = 100 #私有屬性
print('我是靜態')
car1.jia_shi() #可以間接通過公有方法呼叫
#我是靜態
總結:私有方法和私有屬性只能在類中被呼叫!
類中的屬性與方法
class Car(): a = '我是類的屬性' def jia_shi(self): #公有方法 print(self.a) @classmethod #類方法,用該裝飾器進行裝飾 def setleifangfa(cls,i): #一般以cls作為第一個引數 cls.a = i @classmethod def getleifangfa(cls): return cls.a car1.setleifangfa('我要改變私有') #我要改變私有 print(car1.getleifangfa()) #我要改變私有
總結:例項物件可以呼叫類的方法與屬性,同樣可以被類在自身中呼叫
靜態方法
靜態方法中不需要額外新增定義引數,因此在靜態方法中必須通過類物件來引用
靜態方法是一種普通函式,位於定義的名稱空間中,它不會對任何例項類進行操作。
class Car():
a = '我是靜態方法'
@staticmethod
def get():
print(Car.a)
car1=Car()
car1.get()
#我是靜態方法
總結:靜態方法用 @staticmethod裝飾器裝飾,它可以被類,例項物件呼叫!
繼承
父類可以是一個或者多個,不用繼承則空著
繼承分為多繼承與單繼承 注意:父類的屬性,方法可以繼承給子類,父類的私有屬性,方法無法被繼承!
class Super_A(object):
def __init__(self):
self.name = 'jack'
def info_a(self):
print('我是父類')
class Super_B(Super_A):
def __init__(self):
Super_A.__init__(self) #呼叫父類的init函式
super().__init__() #也可以用super方法繼承過來
self.age = 18
def info_b(self):
print(self.name,self.age)
car2 = Super_B()
car2.info_a()
car2.info_b()
#我是父類
#jack 18
總結:派生類定義 init()時,不會自動呼叫基類的_init_()函式,想要得到基類的_init()中的資訊,由派生類呼叫基類的_init()函式來對它進行恰當的初始化。
多繼承
class Person():
def run(self): # 公開方法在子類中可以直接訪問,也可以被覆蓋
print('Person 會跑')
def eat(self):
print('Person 會吃')
class Man(Person):
def fight(self):
print('Man 打架')
class Woman(Person):
def taobao(self):
print('Woman 淘寶')
class NvHanzi(Woman, Man): # Hanzi繼承了Man、Woman的函式和屬性
pass # 空,什麼都不做
hanzi = NvHanzi()
hanzi.run()
hanzi.eat()
hanzi.taobao()
hanzi.fight()
執行結果:
Person 會跑
Person 會吃
Woman 淘寶
Man 打架
修改父類的方法,也叫重寫
class Person():
def run(self): # 公開方法在子類中可以直接訪問,也可以被覆蓋
print('Person 會跑')
def eat(self):
print('Person 會吃')
class Man(Person):
def run(self): # 在子類中修改父類的方法,會覆蓋Person類(父類)的run函式
print('Man在跑')
m = Man() # 自動呼叫父類的建構函式
m.run() # Man類中覆蓋父類中的run函式,m呼叫的是Man類中的run函式
執行結果:
Man在跑
多型
多型是面嚮物件語言的一個基本特性,多型意味著變數並不知道引用的物件是誰,根據引用物件的不同表現不同的行為方式。
class ChuiFengJi: # 我們叫具有吹風功能的事物,叫吹風機
def chui(self): # 吹風功能
print("吹風機 能吹風")
class MeiDi(ChuiFengJi):
def chui(self):
print("美的 能吹風")
class FeiLiPu(ChuiFengJi):
pass
def who_zai_chui(arg):
arg.chui()
c = ChuiFengJi()
m = MeiDi()
f = FeiLiPu()
who_zai_chui(c)
who_zai_chui(m)
who_zai_chui(f)
執行結果:
吹風機 能吹風
美的 能吹風
吹風機 能吹風
由於Python是動態語言,所以,傳遞給函式 who_zai_chui(a)的引數 a 不一定是 ChuiFengJi 或 ChuiFengJi 的子型別。
任何資料型別的例項都可以,只要它有一個chui()的方法即可,這就是多型。
鴨子型別
鴨子型別:
“當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就可以被稱為鴨子。”
在鴨子型別中,不關注物件的型別,只關注它是如何使用的。
比如:吹風機吹風這個功能,在鴨子型別中,只關注它能不能打吹風,而不關心它是誰。
class ChuiFengJi: # 我們叫具有吹風功能的事物,叫吹風機
def chui(self): # 吹風功能
print("吹風機 能吹風")
class MeiDi(ChuiFengJi):
def chui(self):
print("美的 能吹風")
class FeiLiPu(ChuiFengJi):
pass
class PiXie: # PiXie具有吹風的功能,我們就稱PiXie是吹風機,這就是鴨子型別
def chui(self):
print("皮鞋 能吹風")
class WenQuXing: # 不具有吹風的功能,就不是吹風機
pass
def who_zai_chui(arg): # 測試函式,test只接受引數,但是不關心引數arg的型別
arg.chui() # 只關心arg能不能呼叫call函式,不關心它的型別
c = ChuiFengJi()
m = MeiDi()
f = FeiLiPu()
p = PiXie()
w = WenQuXing()
who_zai_chui(c)
who_zai_chui(m)
who_zai_chui(f)
who_zai_chui(p)