Python面向對象基礎

NOTE:
重要強調:
    Python的做用域和命名空間
(1)命名空間 是從命名到對象的映射
    ①內置命名空間
    ②全局命名空間:模塊
    ③本地命名空間:模塊中的函數和類
(2)做用域   是一個 Python 程序能夠直接訪問命名空間的正文區域
    
一:簡介
            類:用來描述具備相同的屬性和方法的對象的集合
        方法:類中定義的函數
      類變量:類變量在整個實例化的對象中是公用的。
                    類變量定義在類中且在函數體以外。類變量一般不做爲實例變量使用。
    實例變量:定義在方法中的變量,只做用於當前實例的類。(注意區分實例變量和類變量)

    實例變量用於對每個實例都是惟一的數據,類變量用於類的全部實例共享的屬性和方法
    用構造方法初始化的屬性叫作實例變量,直接在類中定義的屬性叫作類變量。

   方法重寫:若是從父類繼承的方法不能知足子類的需求,能夠對其進行改寫,這個過程叫方法的覆蓋(override)
       實例化:建立一個類的實例,類的具體對象
           對象:經過類定義的數據結構實例    

二:語法格式
    
    class ClassName:
            <statement-1>
            <statement-N>

三:類對象

    類對象支持兩種操做:屬性引用和實例化。
    (1)類對象建立後,類命名空間中全部的命名都是有效屬性名MyClass.f
    (2)實例化:將類對象看做是一個返回新的類實例的無參數函數x = MyClass()
    
四:類屬性

    公有屬性:在類中定義,能夠在類間調用,能夠經過析構函數進行初始化
    私有屬性:在類中定義,以雙下劃線開始,在類外不能被直接調用,只能被類內部方法使用!
    調用方法:用公有方法返回!

五:類方法

    (1)類的方法與普通的函數只有一個特別的區別——它們必須有一個額外的第一個參數名稱,
    按照慣例它的名稱是 self
    (2)在類的內部,使用 def 關鍵字來定義一個方法,與通常函數定義不一樣,
    類方法必須包含參數 self, 且爲第一個參數,self 表明的是類的實例
    (3)兩個下劃線開頭,聲明該方法爲私有方法,只能在類的內部調用 ,不能在類地外部調用
    (4)類的專有方法

六:構造函數

    類有一個名爲 __init__() 的特殊方法(構造方法),
    該方法在類實例化時會自動調用類有一個名爲 __init__() 的特殊方法(構造方法),
    該方法在類實例化時會自動調用
    能夠聲明帶默認參數的實例變量!

七:析構函數

    實例化的對象調用結束時候調用!

八:類的繼承

        (1)語法結構

        class DerivedClassName(BaseClassName1):
                    <statement-1>
                    .
                    <statement-N>

        (2)多類繼承的時候,新式類(python3)按照廣度優先的原則,
        (找一個爸爸,再找下一個爸爸。。。。)
    
        class DerivedClassName(Base1, Base2, Base3):
                <statement-1>
                .
                    <statement-N>

    (3)基類名與派生類定義在同一個做用域中,除了類,還能夠用表達式,
    基類定義在另外一個模塊中時這一點很是有用:
        class DerivedClassName(modname.BaseClassName):
    這種寫法在模塊化程序中很重要!

    (4)方法重寫

    ①父類方法的功能不能知足你的需求,能夠在子類重寫你父類的方法    
    super(Child,c).myMethod() #用子類對象調用父類已被覆蓋的方法
          子類,對象, 方法
    ②派生類對基類的方法重寫,重寫後的基類方法叫作費捆綁方法,
    不能直接調用,須要使用super函數。

    注意:

    ①子類不重寫 __init__,實例化子類時,會自動調用父類定義的 __init__。
    ②重寫了__init__ 時,實例化子類,就不會調用父類已經定義的 __init__
    ③若是重寫了__init__ 時,要繼承父類的構造方法,可使用 super 關鍵字
        super(子類,self).__init__(參數1,參數2,....)
        父類名稱.__init__(self,參數1,參數2,...)
    
八:多態和封裝

    「當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就能夠被稱爲鴨子。」
    在鴨子類型中,關注的不是對象的類型自己,而是它是如何使用的。
    例如,在不使用鴨子類型的語言中,咱們能夠編寫一個函數,它接受一個類型爲鴨的對象,
    並調用它的走和叫方法。在使用鴨子類型的語言中,這樣的一個函數能夠接受一個任意類型的對象,
    並調用它的走和叫方法。若是這些須要被調用的方法不存在,那麼將引起一個運行時錯誤。
    任何擁有這樣的正確的走和叫方法的對象均可被函數接受的這種行爲引出了以上表述,
    這種決定類型的方式所以得名。

    http://www.php.cn/python-tutorials-366356.html

    (關於多態不是太懂!)

php

 1 # -------------------------------------------------------------------------------------------------------------#
 2 # 建立類
 3 # -------------------------------------------------------------------------------------------------------------#
 4 
 5 
 6 class MyClass:                      # 類的命名爲大駝峯原則
 7     """一個簡單的類實例"""
 8     i = 12345                       # 類的公有屬性
 9 
 10     def __init__(self, real):       # 帶參數的構造函數(方法)
 11         self.r = real  12         # self.i = imag
 13 
 14     def func(self):                     # 類的方法和普通函數的區別
 15         m = self.i + self.r  16         return m  17 # -------------------------------------------------------------------------------------------------------------#
 18 # 類的實例化
 19 # -------------------------------------------------------------------------------------------------------------#
 20 
 21 
 22 print("------------------------類的實例化-----------------------------------")  23 x = MyClass(2)  24 y = MyClass(3)  25 # print(x.__doc__)
 26 # 訪問類的屬性和方法
 27 print("MyClass 類的屬性 i 爲:", x.i)  28 print("MyClass 類的屬性 i 爲:", y.i)  29 
 30 # 對於可變對象如列表、字典、集合,應該聲明爲實例變量,由於實例化後的對象會改變原來的值!
 31 x.i = 23
 32 print("實例化X後 i 爲:", x.i)  33 print("實例化Y後 i 爲:", y.i)  34 print("MyClass 類的方法 f 輸出爲:", x.func())  35 
 36 # -------------------------------------------------------------------------------------------------------------#
 37 # 類的繼承
 38 # -------------------------------------------------------------------------------------------------------------#
 39 print("------------------------類的繼承-------------------------------------")  40 
 41 
 42 # 定義基類
 43 class People:  44     # 定義類變量
 45     # name = ''
 46     # age = 0
 47     # 定義私有屬性,私有屬性在類外部沒法直接進行訪問
 48     # __weight = 0
 49     # 定義構造方法,初始化類變量的值
 50 
 51     def __init__(self, n, a, w):    # 構造函數
 52         # print('調用了構造函數') # 測試構造函數的調用
 53         self.name = n  54         self.age = a  55         self.__weight = w  56         # 上面的變量能夠所有定義爲私有變量!由於在外部沒有必要使用!
 57 
 58     def speak(self):  59         print("%s 說: ’我 %d 歲 %dkg’" % (self.name, self.age, self.__weight))  60 
 61     def my_print(self, name):  62         print(self.name)    # self的做用是類級別上的變量
 63         print(name)         # 不帶self多是變量的值
 64 
 65     def get_name(self):     # OPP家族傳統理念:Getter + Setter
 66         return self.name    # 爲了獲得類中的數據而且抱枕數據的安全(無受保護的數據類型)
 67 
 68     def get_age(self):      # 經過self實現內容的間接調用
 69         return self.age  70 
 71     # @property #
 72     def get_weight(self):  # 經過self實現內容的間接調用
 73         return self.__weight
 74 
 75     def __del__(self):      # 注意學習python的垃圾回收機制
 76         print('調用了父析構函數')  77 # 總結:對於面向對象的封裝來講,其實就是使用構造方法將內容封裝到對象中,
 78 # 經過對象或者self間接的調用內容
 79 
 80 # 繼承:子能夠繼承父親的全部內容
 81 # 定義派生類
 82 
 83 
 84 class Student(People):  85 
 86     def __init__(self, n, a, w, g):  87         self.__grade = g  88         People.__init__(self, n, a, w)          # 調用父類的構造函數
 89 
 90     # 保變量的值不被改變 ,又要獲得值
 91     def lo_ol(self):  92         print('I am not a good student!')  93         print('My grade is %d' % self.__grade)  94 
 95     def __del__(self):          # 注意學習python的垃圾回收機制
 96         print('調用了子析構函數')  97 
 98 
 99 myInfo = People('faith', 24, 60) 100 myInfo.speak() 101 myInfo.age = 10
102 myInfo.speak() 103 print(myInfo.age)               # 類外直接使用
104 
105 
106 print("------------------------測試派生類-------------------------------------") 107 # 經過上面的代碼能夠獲得下面的結論:
108 # 析構函數在對象釋放的時候調用
109 # 能夠直接在類外訪問類的基本屬性
110 # 不能在類外直接訪問類的私有屬性
111 
112 stud = Student('faith', 2, 2, 2) 113 stud.lo_ol() 114 stud.speak() 115 print("體重", stud.get_weight()) 116 # 方法重寫
117 
118 
119 class Parent:   # 定義父類
120     def mymethod(self): 121         print('調用父類方法') 122 
123 
124 class Child(Parent):  # 定義子類
125     def mymethod(self): 126         print('調用子類方法') 127 
128 
129 print("------------------------測試方法重寫-------------------------------------") 130 c = Child()          # 子類實例
131 c.mymethod()         # 子類調用重寫方法
132 super(Child, c).mymethod()  # 用子類對象調用父類已被覆蓋的方法
133 
134 # 靜態方法和類方法
135 print("------------------------測試靜態方法和類方法-------------------------------------") 136 
137 
138 class Apple: 139     def fun1(self): 140         return 'normal'
141 
142     @staticmethod       # 靜態方法
143     def fun2(): 144         return 'staticmethod'
145 
146  @classmethod 147     def fun3(cls):      # 類方法(可以訪問類屬性)
148         return 'classmethod'
149 
150 
151 print(Apple.fun1)   # 非捆綁調用
152 print(Apple.fun2) 153 print(Apple.fun3) 154 print("-"*80) 155 
156 
157 apple = Apple()     # 捆綁調用
158 print(apple.fun1) 159 print(apple.fun2) 160 print(apple.fun3) 161 
162 print("-"*80) 163 
164 apple1 = Apple()    # 捆綁調用
165 print(apple1.fun1) 166 print(apple1.fun2) 167 print(apple1.fun3)
相關文章
相關標籤/搜索