Python--類和對象學習

一、面向對象編程概述

1、面向對象編程(OOP)

  • 面向對象:以具體的事物(對象)為單位,考慮它的屬性(特征)及動作(行為),關注整體。java、c#也是面向對象編程。

  • 例子解讀(把大象裝進冰箱):為了把大象裝進冰箱,需要做三個動作(行為)。每個動作有一個執(zhí)行者,它就是對象,這里對象是冰箱。

    1. 冰箱,你給我把門打開(冰箱.開門())
    2. 冰箱,你給我把大象裝進去(冰箱.裝大象())
    3. 冰箱,你給我把門關上(冰箱.關門())
      依次做這些動作,就能把大象裝進冰箱。
  • 三大特征

    (1)封裝(信息隱蔽技術):類的封裝、函數(shù)封裝,方便調用。

    #創(chuàng)建一個list1列表對象,我們不需知道列表對象里方法的具體實現(xiàn)過程,封裝好了,用方法名直接調用即可
    >>>list1 = [1,5,2,6]
    >>>list1.append(10)
    >>>list1
    [1,5,2,6,10]
    >>>list1.sort()
    [1,2,5,6,10]
    

    (2)繼承:子類繼承父類的方法和屬性

    #創(chuàng)建一個Mylist類,繼承l(wèi)ist類的屬性和方法
    class Mylist(list):
      pass
    
    >>>list2 = Mylist()
    >>>list2.append(4)
    >>>list2.append(5)
    >>>list2.append(6)
    >>>list2
    [4,5,6] 
    

    類名后面緊接著是(object),表示該類是從哪個類繼承下來的。通常,如果沒有合適的繼承類,就使用object類,這是所有類最終都會繼承的類。

    (3)多態(tài):不同對象對同一方法響應不同的行動,而無需明確知道這個對象是什么。即一個方法,多種形態(tài),就是多態(tài)。

    class Person(Object):
      def func(self):
          print('我是人!')
    class Girl(Person):
      def func(self):
          print('我是妹子!')
    class Boy(Person):
      def func(self):
          print('我是漢子!')
    def func1(x): #涉及知識點:靜態(tài)/動態(tài)類型語言,file-like object,“鴨子類型”(duck typing)
      x.func()
    
    >>>a = Person()
    >>>b = Girl()
    >>>c = Boy()
    >>>a.func1()
    我是人!
    >>>b.func1()
    我是妹子!
    >>>c.func1()
    我是漢子!
    

2、面向過程編程

  • 面向過程:以一個具體的流程為單位,考慮它的實現(xiàn)方法,關心的是功能的實現(xiàn)(耦合性比較強)。C語言是面向過程編程。

  • 例子解讀(把大象裝進冰箱):為了把大象裝進冰箱,需要3個過程。

    1. 把冰箱門打開(得到打開門的冰箱)
    2. 把大象裝進去(打開門后,得到里面裝著大象的冰箱)
    3. 把冰箱門關上(打開門、裝好大象后,獲得關好門的冰箱)
      每個過程有一個階段性的目標,依次完成這些過程,就能把大象裝進冰箱。

3、類和對象

  • 類是對一組具有相同特性(屬性)和相同行為(方法)的事物的概括,是抽象的模板;對象是客觀世界實際存在的事物都是一個對象,即“萬物萬事皆對象”。對象=屬性+方法

  • 類是對象的模板,對象是類的實例

    #定義一個人類Person,類名首字母要大寫
    class Person:
          def __init__(self,name,sex,age):
          self.name=name     #name,sex,age是類的屬性
          self.sex=sex
          self.age=age 
      #定義類的方法
          def introduce(self):
              print('大家好,我叫%s,%s,今年%s歲'%(self.name,self.sex,self.age))
          def eat(self):
          print('%s:好餓了,想吃大餐,畢竟吃飽了,才有力氣減肥,嘻嘻'%self.name)
          def run(self):
          print('%s:運動讓人快樂,跑步走起!'%self.name)
          def sleep(self):
          print('%s:不嗨了,早睡早起身體棒!'%self.name)
    
    #實例化,創(chuàng)建一個對象
    >>>xiao_ming = Person('李小明','男','24')
    #調用Person類的方法
    >>>xiao_ming.introduce()
    大家好,我叫李小明,男,24歲
    >>>xiao_ming.eat()
    李小明:好餓了,想吃大餐,畢竟吃飽了,才有力氣減肥,嘻嘻
    
  • 拓展

    1、什么是類、類對象、實例對象?

     #這是一個類,定義完之后也是一個類對象
     class C:  
         count=0
     -----------------------------------------
     >>>a=C() #a、b、c是實例對象
     >>>b=C()
     >>>c=C()
     >>>a.count
     0
     >>>b.count
     0
     >>>c.count
     0
     ---------------------------------------
     >>>c.count+=10  #實例對象覆蓋了類對象里的屬性
     >>>c.count
     10
     >>>a.count
     0
     >>>b.count
     0
     ---------------------------------------
     >>>C.count+=100
     >>>C.count
     100
     >>>a.count
     100
     >>>b.count
     100
     >>>c.count
     10
    
    graph TB
    task1("類定義 C")-->task2("類對象 C")
    task2-->task3("實例對象 a")
    task2-->task4("實例對象 b")
    task2-->task5("實例對象 c")
    

二、self是什么

  • 類的定義里,self會出現(xiàn)在函數(shù)的第一個參數(shù)里(python的默認要求,必填參數(shù),這是與普通函數(shù)的一個區(qū)別),通過哪個對象調用的方法,則self就是哪個對象

  • 例子解讀:(還是用上述Person類)

    #實例化,創(chuàng)建xiao_ming對象
    >>>xiao_ming = Person('李小明','男','24')
    #通過xiao_ming這個對象來調用introduce方法
    >>>xiao_ming.introduce()
    大家好,我叫李小明,男,今年24歲
    
    #實例化,創(chuàng)建zhangli對象
    >>>zhangli = Person('張麗','女','18')
    #通過zhangli這個對象來調用introduce方法
    >>>zhangli.introduce()
    大家好,我叫張麗,女,今年18歲
    

    def introduce(self):

    ? print('大家好,我叫%s,%s,今年%s歲'%(self.name,self.sex,self.age))

    當對象xiao_ming調用introduce()方法時,self會調用xiao_ming的name,sex,age屬性作為參數(shù)輸入,然后print對應格式輸出自我介紹;而zhangli這個對象調用introduce()時,則傳入的是zhangli的name,sex,age。

三、訪問限制:公有與私有

  • C++中,用public和private標識公有變量與私有變量,而在python中,默認情況下,對象的屬性、方法都為公有的,用.點操作符來訪問

    class Car:
          name = '本田' 
    >>>c1 = Car()
    >>>c1.name #用.點操作符來訪問
    '本田'
    >>>c1.name = '豐田' #外部可自由修改c1實例的name屬性
    >>>c1.name
    '豐田'
    
  • 若要實現(xiàn)類似于私有變量的特征,python內(nèi)部采用了一種叫做name mangling名字改編的技術。在python中定義私有變量,只需在變量名或函數(shù)名前加上兩個下劃線"__",則該函數(shù)或變量就會變?yōu)樗接校挥袃?nèi)部可以訪問,外部不能訪問。

    class Car:
          __name = '本田' #定義成私有變量 
    >>>c1 = Car()
    >>>c1.name #直接用點操作符訪問,會報錯,屬于外部調用
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'Car' object has no attribute 'name'
    >>>c1.__name #也會報錯
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'Car' object has no attribute '__name'
    

    在外部,私有變量”被隱藏“起來了,不能訪問。理論上,若要訪問私有變量,可通過在類中定義方法getname,內(nèi)部調用來訪問:

    class Car:
      __name = '本田'
      def getname(self):
        return self.__name
    >>>c2 = Car()
    >>>c2.__name  #仍會報錯
    >>>c2.getname() #成功運行,此時的getname()是在內(nèi)部調用name屬性
    '本田'
    #注意一下下面這種錯誤的修改私有變量方式
    >>>c2.__name = '豐田'
    #表面上看,外部代碼“成功”地修改了__name變量,但實際上這個__name變量和class內(nèi)部的__name變量不是一個變量!
    >>>c2.__name
    '豐田'
    >>>c2.getname()#返回class內(nèi)部self.__name
    '本田'
    

    雖然上述代碼成功運行,而實際上,私有變量只是名字重整,被python改了名字,變?yōu)榱?em>類名_變量名而已。其實python是偽私有機制,python的類是無權限控制的,變量可被外部調用。

    >>>c2._Car__name #還是用.操作符,對象._類名__變量名即可
    '本田'
    
  • 注意:

    1、不同版本的Python解釋器可能會把__name改成不同的變量名,不一定是_Car__name!

    2、在Python中,變量名類似__xxx__的,也就是以雙下劃線開頭,并且以雙下劃線結尾的,是特殊變量(魔法方法),特殊變量是可以直接訪問的,不是private變量。所以,不能用__name__、__score__這樣的變量名來定義私有變量。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

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