Python:面向?qū)ο?/h2>

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) #這不能作為寵物!
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容