
1. 類與對象
1.1 類與對象的創(chuàng)建
- 類名為駝峰式命名法,每個(gè)單詞開頭大寫
- 每個(gè)類都自動(dòng)繼承Object類
- 類中的每個(gè)屬性都必須有初始值,哪怕這個(gè)值是0或空字符串
- 可以通過“類名.屬性”的方式修改類的普通屬性
# 類的創(chuàng)建
# 由于類的方法會在下面講述,所以這里創(chuàng)建的類只有屬性
class Person:
name = 'Licy'
age = '18'
# 對象的創(chuàng)建
person1 = Person()
person2 = Person()
# 同一類的不同對象的初始屬性相同
print(person1.age) #18
print(person1.name) #Licy
print(person2.age) #18
print(person2.name) #Licy
# 可修改對象的屬性,但類中屬性不變
person1.age = 12
print(person1.age) #12
# 可修改類的屬性,對象屬性都發(fā)生改變
Person.age = 100
print(person2.age) #100
1.2 類的普通方法
- 每個(gè)方法中形參self必不可少,還必須位于其他形參的前面,self代表當(dāng)前對象
- 可以在類的外面,通過對象添加其獨(dú)有的屬性,其余對象不能調(diào)用
- 可以通過“對象名.方法名()”的方式調(diào)用類中的方法
- 普通方法不能通過“類名.方法名()的方式調(diào)用”
- 類中普通方法之間的相互調(diào)用要通過“self.方法名”的方式
class Phone:
# 創(chuàng)建屬性
brand = "xiaomi"
price = 4999
def testSelf(self):
print(self)
def call(self):
print("正在打電話")
def color(self):
print("顏色是",self.phoneColor)
# 創(chuàng)建類的對象
phone1 = Phone()
phone2 = Phone()
# self代表當(dāng)前對象
print(phone1) #<__main__.Phone object at 0x000001F3140072C8>
phone1.testSelf() #<__main__.Phone object at 0x000001F3140072C8>
# 調(diào)用方法
phone1.call() #正在打電話
phone2.call() #正在打電話
# phone2不能調(diào)用color方法,因?yàn)閜hone2沒有color屬性
phone1.phoneColor = 'blue'
phone1.color() #正在打電話
1.3 構(gòu)造器與__ init() __方法
- __ init() __被稱為類的構(gòu)造器,也稱為初始化方法,也屬于魔術(shù)方法之一
- 當(dāng)創(chuàng)建類的實(shí)例時(shí),Python就會自動(dòng)調(diào)用__ init() __,這一方法動(dòng)態(tài)地創(chuàng)建屬性
- __ init() __在使用參數(shù)情況下使同一類的不同對象具有不同相同屬性
class Phone:
def __init__(self,brand,price):
self.brand = brand
self.price = price
def message(self):
print(self.brand,self.price)
# 創(chuàng)建對象
phone1 = Phone("huawei",2999)
phone2 = Phone("xiaomi",2399)
# message()方法
phone1.message() #huawei 2999
phone2.message() #xiaomi 2399
# 修改屬性
phone1.brand = "xiaomi"
phone1.message() #xiaomi 2999
1.4 類方法
- 類方法通過裝飾器“@classmethod”來修飾,屬于類的方法,不依靠對象的存在而存在
- 類方法的參數(shù)為固定參數(shù)為cls,代表當(dāng)前類,cls不能調(diào)用非類屬性,因?yàn)轭惒荒苷{(diào)用非類屬性
- 可以通過“類名.類方法”的方式調(diào)用類方法,對象也可以調(diào)用類方法
- 類方法中不能調(diào)用普通方法,因?yàn)轭惙椒ㄖ胁荒苁褂胹elf
class Phone:
# 類屬性
a = 123
def __init__(self,brand):
self.brand = brand
def call(self):
print("正在打電話")
@classmethod
def test(cls):
print("這是一個(gè)類方法",cls.a)
# 未創(chuàng)建對象,可以通過類名調(diào)用類方法
Phone.test()
# 未創(chuàng)建對象,可以通過類名調(diào)用類屬性
print(Phone.a)
# 普通方法可以調(diào)用類方法
p1 = Phone("huawei")
p1.test()
1.5 靜態(tài)方法
靜態(tài)方法通過裝飾器“@staticmethod”來修飾,無固定參數(shù)
靜態(tài)方法與類方法及其相似,可調(diào)用的內(nèi)容一致,但類方法是可通過cls和類名調(diào)用,靜態(tài)方法只能用類名調(diào)用

1.6 魔術(shù)方法
魔術(shù)方法就是一個(gè)類/對象中的方法,和普通方法唯一的不同時(shí),普通方法需要調(diào)用!而魔術(shù)方法是在特定時(shí)刻自動(dòng)觸發(fā)。
-
__ init __:
初始化魔術(shù)方法 觸發(fā)時(shí)機(jī):初始化對象時(shí)觸發(fā)(不是實(shí)例化觸發(fā),但是和實(shí)例化在一個(gè)操作中) 參數(shù):至少有一個(gè)self,接收對象 返回值:無 作用:初始化對象的成員 注意:使用該方式初始化的成員都是直接寫入對象當(dāng)中,類中無法具有其中的自創(chuàng)屬性 -
__ new __:
實(shí)例化魔術(shù)方法 觸發(fā)時(shí)機(jī): 在實(shí)例化對時(shí)觸發(fā) 參數(shù):至少一個(gè)cls 接收當(dāng)前類 返回值:必須返回一個(gè)對象實(shí)例 作用:實(shí)例化對象,開辟內(nèi)存空間給__init__ 注意:實(shí)例化對象是Object類底層實(shí)現(xiàn),其他類繼承了Object的__new__才能夠?qū)崿F(xiàn)實(shí)例化對象。 沒事別碰這個(gè)魔術(shù)方法,先觸發(fā)__new__才會觸發(fā)__init__ -
__ call __:
調(diào)用對象的魔術(shù)方法 觸發(fā)時(shí)機(jī):將對象當(dāng)作函數(shù)調(diào)用時(shí)觸發(fā) 對象() 參數(shù):至少一個(gè)self接收對象,其余根據(jù)調(diào)用時(shí)參數(shù)決定 返回值:根據(jù)情況而定 作用:可以將復(fù)雜的步驟進(jìn)行合并操作,減少調(diào)用的步驟,方便使用 注意:必須重寫__call__方法才能將對象當(dāng)作函數(shù)使用 -
__ del __:
析構(gòu)魔術(shù)方法 觸發(fā)時(shí)機(jī):當(dāng)對象沒有用(沒有任何變量引用該對象)的時(shí)候被觸發(fā) 參數(shù):一個(gè)self 返回值:無 作用:使用完對象是回收資源 注意:del不一定會觸發(fā)當(dāng)前方法,只有當(dāng)前對象沒有任何變量接收時(shí)才會觸發(fā) -
__ str __:
觸發(fā)時(shí)機(jī):使用print(對象名)或者str(對象名)的時(shí)候觸發(fā) 參數(shù):一個(gè)self接收對象 返回值:必須是字符串類型 作用:print(對象名)時(shí)進(jìn)行操作,得到字符串,通常用于快捷操作,而不再打印出對象地址 注意:無
2. 私有化
2.1 私有化屬性
在Python中,可以使用"__"添加在一變量之前,來表示對這一變量的私有化,具有以下特點(diǎn):
- 私有化屬性不能直接調(diào)用、修改
- 私有化屬性可以通過getXxx和setXxx來調(diào)用和修改
class Student:
def __init__(self,name,age):
self.__name = name
self.__age = age
def setAge(self,age):
self.__age = age
def getAge(self):
return self.__age
s = Student("zhangsan",18)
# 不能直接調(diào)用私有屬性,會報(bào)異常
# print(s.__age,s.__name)
# 可以通過getAge()方法調(diào)用Age
print(s.getAge()) #18
# 可以通過setAge()方法修改Age
s.setAge(100)
print(s.getAge()) #100
2.2 使用裝飾器實(shí)現(xiàn)私有化
- 可以使用裝飾器"@property"來修飾函數(shù)以實(shí)現(xiàn)私有化
- 可以使用裝飾器"@同名函數(shù)名.setter"來修飾函數(shù)以實(shí)現(xiàn)修改屬性
- 用裝飾器的方式實(shí)現(xiàn)私有化,調(diào)用與修改屬性與為私有化之前相同
class Student:
def __init__(self,name,age):
self.__name = name
self.__age = age
@property
def age(self):
return self.__age
# 同一類中不能有函數(shù)名不能相同,但使用構(gòu)造器"@同名函數(shù)名.setter"可以實(shí)現(xiàn)同名函數(shù)
@age.setter
def age(self,age):
self.__age = age
s = Student("zhangsan",18)
# 使用裝飾器@property后,可以像為私有化之前"對象.屬性"的方式調(diào)用對象
print(s.age) #18
# 修改屬性值,和原來未私有化之前的方式相同
s.age = 100
print(s.age) #100
3. 繼承
3.1 實(shí)現(xiàn)繼承關(guān)系
- 定義子類時(shí),必須在括號內(nèi)指定父類的名稱。
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def run(self):
print(self.name + " is running")
class Student(Person):
pass
s = Student("Peter",18)
s.run() #Peter is running
3.2 父類方法的重寫
- 重寫后,也可以使用super關(guān)鍵字調(diào)用父類的方法
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def run(self):
print("父類的跑步方法")
class Student(Person):
def __init__(self,name,age,id):
self.name = name
self.age = age
self.id = id
def run(self):
super().run()
print("子類的跑步方法 ")
s = Student("Peter",18,12345)
s.run()
3.3 多重繼承
- Python可以實(shí)現(xiàn)多繼承
- 若多繼承中父類有同名的方法,可以使用魔術(shù)方法__ mro __來檢查搜索順序
class A:
def test(self):
print("--------AAA")
class B:
def test(self):
print("--------BBB")
class C(B,A):
def func(self):
super().test()
c = C()
c.test() #--------BBB
c.func() #--------BBB
# 檢查搜索順序
print(C.__mro__) #(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
4. 多態(tài)
4.1 多態(tài)的實(shí)現(xiàn)
- 在Java中多態(tài)涉及的類必須具有繼承關(guān)系,而在Python中多態(tài)的實(shí)現(xiàn),可以不具備繼承關(guān)系,所以Python沒有真正意義上的多態(tài)
class Person:
def show(self,pet): # pet即可接收Pet,也可接收Cat、Dog,也可接收Tigger
if isinstance(pet,Pet): # 判斷對象(pet)是否為類(Pet)以及是否為其子類
print("{}的名字叫{}".format(pet.role,pet.nickname))
else:
print("這不能作為寵物!")
class Pet:
pass
class Cat(Pet):
role = "小貓"
def __init__(self,nickname):
self.nickname = nickname
class Dog(Pet):
role = "小狗"
def __init__(self,nickname):
self.nickname = nickname
class Tiger:
role = "老虎"
def __init__(self,nickname):
self.nickname = nickname
c = Cat("喵喵")
d = Dog("汪汪")
t = Tiger("吼吼")
p = Person()
p.show(c) #小貓的名字叫喵喵
p.show(d) #小狗的名字叫汪汪
p.show(t) #這不能作為寵物!