1. 程式人生 > >Python系統學習第十課

Python系統學習第十課

python面向物件繼承

  • 基礎

  • 公有私有

  • 繼承

  • 組合

  • 魔法函式

    • 魔法函式概述
    • 建構函式魔法函式
    • 運算類魔法函式
  • OO : 面向物件

  • OOA :面向物件的分析

  • OOD : 面向物件的設計

  • OOI :XXX的實現

  • OOP :XXX的程式設計

  • OOA -> OOD -> OOI :面向物件的實現過程

類和物件的概念

  • 類,抽象名詞,代表一個集合,共性的事物
  • 物件:具象的事物,單個個體
  • 類和物件的關係
    • 一個抽象,代表一類事物
    • 一個具象,代表某一個個體

類中的內容,應該具有兩個內容

  • 表明事物的特徵,叫做屬性(變數)
  • 表明事物功能或動作,稱為成員方法(函式)

類的基本實現

  • 類的命名
  • 大駝峰原則
  • 儘量避開跟系統命名相似的命名

如何宣告一個類

  • 必須用class關鍵字
  • 類由屬性和方法構成,其他不允許出現
  • 成員屬性定義可以直接使用變數賦值,如果沒有值,可以使用None
#定義一個類
class Student():
    pass
#定義一個物件
liziqiang = Student()

#再定義一個類,用來描述學習python的學生
class PythonStudent():
    #用None給不確定的值賦值
    name = None
    age = 4
    course = "Python"
    
    def dHomework(self):
        print("zuozuoye")
        return None

#例項化一個物件
lizi = PythonStudent()
print(lizi.
name) print(lizi.age) print(lizi.course) lizi.dHomework()
None
4
Python
zuozuoye

#訪問物件成員

  • 使用點操作符
  • 物件.成員屬性
  • 物件.方法

可以通過預設內建變數檢查類和物件的所有成員

  • 物件所有成員檢測
  • dict前後各有兩個下劃線
  • 物件.dict
  • 類的所有成員
  • class_name.dict
lizi.__dict__
PythonStudent.__dict__
mappingproxy({'__module__': '__main__',
              'name': None,
              'age': 4,
              'course': 'Python',
              'dHomework': <function __main__.PythonStudent.dHomework(self)>,
              '__dict__': <attribute '__dict__' of 'PythonStudent' objects>,
              '__weakref__': <attribute '__weakref__' of 'PythonStudent' objects>,
              '__doc__': None})

類和物件的成員分析

  • 類和物件都介意儲存成員,成員可以歸類所有,也可以歸物件所有
  • 類儲存成員時,使用的是與類關聯的物件
  • 獨享成員函式是儲存在當前物件中
  • 物件訪問一個成員時,如果物件中沒有該成員,嘗試訪問類中的同名成員,如果物件中有詞成員,一定使用物件中的成員
  • 建立物件的時候,類中的成員不會放入物件當中,而是得到一個空物件,沒有成員
  • 通過物件對類中成員重新賦值或者通過物件新增成員時,對應成員會儲存在物件中,而不會修改類成員
class A():
    name = "lizi"
    age = 18
    
    def B():
        self.name = "aaa"
        self.age = 23
        
print(A.name)
print(A.age)
print(id(A.name))
print(id(A.age))

a = A()
print(a.name)
print(a.age)
print(id(a.name))
print(id(a.age))

a.name = "qqqq"
print(a.name)
print(id(a.name))
print(id(A.name))

#說明,當沒有給物件的屬性賦值時,物件和類的屬性指向同一個id,當給賦值以後,就重新分配了記憶體,這個時候就和類的屬性的id不同了
        

        
lizi
18
2475878126456
1883663968
lizi
18
2475878126456
1883663968
qqqq
2475878224928
2475878126456

#關於self

  • self在物件的方法中表示當前物件本身,如果通過物件呼叫一個方法,那麼該物件會自動傳入到當前方法的第一個引數中
  • self不是關鍵字,只是一個用於接受物件的普通引數,理論上可以用任何一個普通變數代替
  • 方法中只有self形參的方法稱為非繫結類的方法,可以通過物件使訪問,沒有self的方法稱為繫結類的方法,只能通過類來訪問
  • 使用類訪問繫結類的方法時,如果類方法中需要訪問當前類的成員,可以通過__class__成員名來訪問
class A():
    name = "lizi"
    age = 18
    
    def B(self):
        self.name = "aaa"
        self.age = 23
        print("my name is {0}".format(self.name))   #此時的self = 物件C,self本身不是關鍵字,用其他字母代替完全沒問題
        print("my age is {0}".format(self.age))

C = A()
C.B()
my name is aaa
my age is 23
class A():
    name = "lizi"
    age = 18
    
    def B(self):
        self.name = "aaa"
        self.age = 23
        print("my name is {0}".format(self.name))   #此時的self = 物件C,self本身不是關鍵字,用其他字母代替完全沒問題
        print("my age is {0}".format(self.age))   #此時訪問的年齡是方法的年齡不是類的年齡
        
    def C():
        print("helo, nice to see you again")
        
D = A()
D.B()
A.C()
D.C()  #不可呼叫,只能通過上邊的類名來訪問


my name is aaa
my age is 23
helo, nice to see you again



---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-4-72a99c7026ec> in <module>()
     15 D.B()
     16 A.C()
---> 17 D.C()


TypeError: C() takes 0 positional arguments but 1 was given
class A():
    name = "lizi"
    age = 18
    
    def B(self):
        self.name = "aaa"
        self.age = 23
        print("my name is {0}".format(self.name))   #此時的self = 物件C,self本身不是關鍵字,用其他字母代替完全沒問題
        print("my age is {0}".format(__class__.age))  #此時訪問的是類的年齡,不是方法的年齡
    def C():
        print(__class__.name)
        print(__class__.age)
        print("helo, nice to see you again")
        
D = A()
D.B()
A.C()
D.C()
my name is aaa
my age is 18
lizi
18
helo, nice to see you again



---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-6-538682ae8e46> in <module>()
     16 D.B()
     17 A.C()
---> 18 D.C()


TypeError: C() takes 0 positional arguments but 1 was given
#關於self的案列
class A():
    name = "lizi"
    age = 99
    addr = "ffff"
    def __init__(self):
        self.name = "liziqiang"
        self.age = 18
    def B(self):
        print(self.name)
        print(self.age)

        
class C():
    name = "llll"
    age = 23
    
a = A()
a.B()

A.B(a)  #此時self被a替換

A.B(A)   #只要括號中的引數是有類的屬性的就不報錯,此時返回的是累的屬性

A.B(C)   #此時傳入的是類例項B,因為b具有name和age屬性,所以就不會報錯

liziqiang
18
liziqiang
18
lizi
99
llll
23

面向物件的三大特性

  • 封裝 :就是對物件的成員進行訪問限制
    • 封裝的三個級別:
      • 公開,public
      • 受保護的,protected
      • 私有的,private
      • public,protected,private不是關鍵字
  • 判別物件的位置
    • 物件外部
    • 物件內部
    • 子類中
  • 私有
    • 私有成員是最高級別的封裝,只能在當前類或者物件中訪問
    • 在成員前面新增兩個下劃線即可,python的私有不是真私有,通過name mangling技術還是可以訪問的。
class person():
    name = "lzi"  #  #name是共有成員
    __age = 19    #  age是私有成員
    
A = person()
print(A.name)
print(A.__age)   #想要在類的外邊訪問私有成員,不可以
lzi



---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-18-d527e434b390> in <module>()
      5 A = person()
      6 print(A.name)
----> 7 print(A.__age)   #想要在類的外邊訪問私有成員,不可以


AttributeError: 'person' object has no attribute '__age'
class person():
    name = "lzi"  #  #name是共有成員
    __age = 19    #  age是私有成員
    
A = person()
print(A.name)
A._person__age = 2222
print(A._person__age)   #name mangling 訪問私有變數
lzi
2222