python的面向物件
面向物件與面向程序
面向程序
- 面向程序思想:需要實作一個功能的時候,看重的是開發的步驟和程序,每一個步驟都需要自己親力親為,需要自己撰寫代碼(自己來做)
面向物件
- 面向物件的三大特征:封裝性、繼承性、多型性
- 面向物件思想:需要實作一個功能的時候,看重的并不是程序和步驟,而是關心誰幫我做這件事(偷懶,找人幫我做)
類與物件
- 物件是面向物件編程的核心,在使用物件的程序中,為了將具有共同特征和行為的一組物件抽象定義,提出了另一個新的概念——類
- 類:抽象的,是一張“手機設計圖”
- 物件:具體的,是一個“真正的手機實體”
- 類是抽象的,在使用的時候通常會找到這個類的一個具體的存在;一個類可以找到多個物件
#學生案例
class Student(): #創建一個學生類
#定義一個info函式,并傳參至self本身
def info(self,name,age,sex):
print('學生的姓名是:',self.name)
print('學生的年齡是:',self.age)
print('學生的性別是:',self.sex)
yinianji = Student() #創建一個具體的物件:一年級
yinianji.info() #實體化物件呼叫定義的info函式
案例
當創建一個物件時,就是用一個模子來制造一個實物
#案例
class Dog(): #定義一個類的形式
#info是一個實體方法,類物件可以呼叫實體方法,實體方法的第一個引數一定是self
def info(self):
#當物件呼叫實體化方法時,python會自動將物件本身的參考作為引數,傳遞到實體方法的第一個引數self里面
print(self)
print("狗祖宗")
#Dog這個類實體化了一個物件 jinmao
jinmao = Dog()
#物件呼叫實體化方法info(),執行info()中封裝的代碼 .表示選擇屬性或方法
jinmao.info()
#列印物件,則默認列印物件在記憶體中的地址,結果等同于info中的print(self)
print(jinmao)
#id(taidamier)則時記憶體地址的十進制形式表示
print(id(jinmao))
-----------------------------------------------------------
<__main__.Dog object at 0x00000190A9DC67F0>
狗祖宗
<__main__.Dog object at 0x00000190A9DC67F0>
1720836712432
屬性和變數
屬性和變數的區別
- 屬性:指某個物件的具體特性
- 變數:指可以更改的量
屬性和變數的判斷依據
- 根據宿主判斷:變數無宿主,屬性有宿主
- 根據宿主的不同又分為物件屬性以及類屬性
物件屬性獲取
- 物件既然有實體方法,也可以有自己的屬性
- 在方法內通過self獲取物件屬性
#物件屬性獲取
class Dog(): #定義一個狗類
def move(self): #移動實體方法
print("moving...")
def attack(self): #咬人實體方法
print("咬人")
#實體化一個狗物件 jinmao
jinmao = Dog()
#給物件添加屬性,以及對應的屬性值
jinmao.name = "xiao"
jinmao.hp = 200
jinmao.atk = 40
jinmao.armor = 100
#通過.成員選擇運算子,獲取物件的屬性值
print("%s 的生命值為:%d" %(jinmao.name,jinmao.hp))
print("%s 的攻擊力為:%d" %(jinmao.name,jinmao.atk))
print("%s 的護甲值為:%d" %(jinmao.name,jinmao.armor))
#通過.成員選擇運算子,獲取物件的實體方法
jinmao.move()
jinmao.attack()
-----------------------------------------------------------
xiao 的生命值為:200
xiao 的攻擊力為:40
xiao 的護甲值為:100
moving...
咬人
關于self
- self就是實體化物件本身
#關于self
class A:
def f(self,data):
print(self.name)
print(data)
o = A()
print(A.f)
print(o.f)
-----------------------------------------------------------
<function A.f at 0x000002725D28ADC0>
<bound method A.f of <__main__.A object at 0x000002725D2467F0>>
- 其中A.f對應的時function 即為一個普通的函式
- o.f為bound method 即在函式上系結了一個物件 —— o
- 結論:o.f 是回傳了一個method object ,而當去呼叫這個object時,他會記住被創建時系結的物件,即回傳該物件,默認引數為self
魔法方法
魔法方法__init__()
__init__方法可以在創建物件時就擁有一些屬性,__init__通常用來做屬性初始化 或 賦值 操作
- 如果類沒有寫__init__方法,python會自動創建,但不會執行任何操作
- 所以一個類里無論自己是否撰寫__init__方法 都一定有__init__方法
案例一
#init方法
class Dog():
#方法,用來做變數初始化 或 賦值 操作,在類實體化物件的時候,會被自動呼叫
def __init__(self,name,hp) -> None:
#__init__方法也可以帶引數
self.name = name
self.hp = hp
print(self.name,self.hp)
#實體化一個物件,并自動呼叫__init__方法
xiaohuang = Dog("小黃",200)
---------------------------------------------------------
class Dog():
def f(self,name,hp):
self.name = name
self.hp = hp
print(self.name,self.hp)
xiaohuang = Dog()
xiaohuang.f("小黃",200)
案例二
#init方法二
class Dog():
def __init__(self,name,skill,hp) -> None:
self.name = name
self.skill = skill
self.hp = hp
def move(self):
print("%s 正在前往事發地點..." % self.name)
def attack(self):
print("%s 咬人 %s..."%(self.name,self.skill))
def info(self):
print("%s 的生命值:%d"%(self.name,self.hp))
#實體化物件時,引數會傳遞到物件的__init__()方法中
jinmao = Dog("金毛","連環咬",200)
hashiqi = Dog("哈士奇","不松口",300)
#直接輸出物件即為地址
print(jinmao)
print(hashiqi)
#不同物件的屬性值的單獨保存
print(id(jinmao.name))
print(id(hashiqi.name))
#同一個類的不同物件,實體方法共享
print(id(jinmao.attack))
print(id(hashiqi.attack))
-----------------------------------------------------------
<__main__.Dog object at 0x000001A3209367F0>
<__main__.Dog object at 0x000001A32089F250>
1800138028976
1800138029168
1800131850880
1800131850880
總結
- 在類內部獲取 屬性 和 實體方法,通過self獲取
- 在類外部獲取 屬性 和 實體方法,通過物件名獲取
- 如果有一個類有多個物件,每個物件的屬性時各自保存的,都有各自獨立的地址
- 實體方法時所有物件共享的,只占用一份記憶體空間
- 類會通過self來判斷是哪個物件,呼叫了實體方法
魔法方法__str__()
該方法用來顯示資訊,通過一個字符串來描述實體物件,該方法需要return一個資料,并且只有self一個引數,在類的外部時用print(物件)列印這個資料(面向用戶)
#str方法
class Person():
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return "此人姓名為%s,此人的年齡為%s"%(self.name,self.age)
p1 = Person("李四",18)
P2 = Person("王五",19)
print(p1)
print(P2)
-------------------------------------------------------------
此人姓名為李四,此人的年齡為18
此人姓名為王五,此人的年齡為19
觸發方式:
1、直接通過print函式去列印
2、通過出發str函式進行轉換
魔法方法__repr__()
通過一個字串描述實體物件的資訊(面向開發人員)
#repr方法
class Person():
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return "此人姓名為%s,此人的年齡為%s"%(self.name,self.age)
p1 = Person("李四",18)
P2 = Person("王五",19)
print(repr(p1))
print(P2)
-------------------------------------------------------------
<__main__.Person object at 0x000001E7D9FD67F0>
此人姓名為王五,此人的年齡為19
#修改repr值
class Person():
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return "此人姓名為%s,此人的年齡為%s"%(self.name,self.age)
def __repr__(self): #更改repr引數值
return "self"
p1 = Person("李四",18)
P2 = Person("王五",19)
print(repr(p1))
print(repr(P2))
print(P2)
-------------------------------------------------------------
self
self
此人姓名為王五,此人的年齡為19
repr與str
在輸出值時當存在str方法便會優先輸出str,repr可以面向開發者,同樣repr方法也可以作為一種方法去輸出str
#repr與str
import datetime
t = datetime.datetime.now()
print(t) #此處輸出的為datetime庫中的類對應的str字串
print(repr(t)) #同時輸出repr進行對比
-------------------------------------------------------------
2022-07-15 23:53:55.418332 #此為對應字串輸出值
datetime.datetime(2022, 7, 15, 23, 53, 55, 418332) #此為repr值
#通過eval函式輸出repr
import datetime
t = datetime.datetime.now()
print(t) #此處輸出的為datetime庫中的類對應的str字串
tmp = repr(t)
result = eval(tmp) #使用eval函式執行輸出repr值的t
print(result)
-------------------------------------------------------------
2022-07-16 00:00:31.144619
2022-07-16 00:00:31.144619
魔法方法__del__()
創建物件后,python解釋器默認呼叫__init__()方法
當洗掉一個物件時,python解釋器也會默認呼叫一個方法,這個方法叫__del__()
#del方法
class Dog():
#創建物件后__init__方法會自動被呼叫
def __init__(self, name):
print("__init__方法被呼叫",name+"出生了")
self.name = name
#當物件執行完畢被洗掉時,__del__方法會自動被呼叫
def __del__(self):
print("__del__方法被呼叫%s死了"%(self.name))
jinmao = Dog("金毛")
---------------------------------------------------------
__init__方法被呼叫 金毛出生了
__del__方法被呼叫金毛死了
繼承
- 子類可以重寫父類的屬性和方法后,依然可以呼叫父類的屬性和方法
- 使用super方法呼叫父類
- 多層繼承關系同樣可以實作
- 裝飾器
class Dog(): #創建父類Dog
def __init__(self) -> None:
self.name = "dog dad"
def skill_dad1(self):
print("attack people")
class Dog2(): #創建父類Dog2
def __init__(self) -> None:
self.name = "dog mom"
def skill_mom1(self):
print("attack dog")
def skill_mom2(self):
print("搖尾巴")
class Son(Dog,Dog2):
#創建子類Son并繼承父類Dog和Dog2,繼承時優先繼承第一個父類Dog
def __init__(self) -> None:
self.name = "dog son"
def skill(self):
print("lick people")
def dad_skill(self):
#通過super方法進行呼叫父類所定義的函式與方法
super().__init__()
super().skill_dad1()
def mom_skill(self):
super().__init__()
super().skill_mom1()
super().skill_mom2()
jinmao = Son()
jinmao.dad_skill()
jinmao.mom_skill()
--------------------------------------------------------------
attack people
attack dog
搖尾巴
多型
- 不同的子物件呼叫相同的父類放啊,產生不同的結果(繼承+重寫)
- 一個父類可以擁有多個子類繼承
#多型
class Dog():
def __init__(self) -> None:
self.name = "dog mom"
def skill(self):
print("attack dog")
#子類/派生類
class Son1(Dog):
def skill(self):
print("attack man")
class Son2(Dog):
def skill(self):
print("attack woman")
class Son3(Dog):
def skill(self):
print("attack child")
#實體化
son1 = Son1().skill()
son2 = Son2().skill()
son3 = Son3().skill()
---------------------------------------------------------
attack man
attack woman
attack child
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/501783.html
標籤:其他
上一篇:迭代器與生成器
下一篇:微信二維碼支付
