1. 程式人生 > 其它 >Python筆記 Ch.12 面向物件

Python筆記 Ch.12 面向物件

技術標籤:python

物件

定義:

一個基礎的類定義

class myClass:
    """這裡是類文件註釋"""

    # 定義一些基本資料成員, 為public
    # 這裡相當於static變數, 是可以直接通過類名訪問的
    name = ""
    age = 0
    # 定義一些私有屬性&方法, 為private
    __weight = 0
    def __privateFun():
        #Do something
        pass
    
    # 初始化方法, 將在類物件建立時被呼叫
def __init__(self): # 執行一些內容 pass # 然後是一些類方法 def fun1(self): pass

幾個注意點:

  1. def關鍵字可以定義一個方法, 但必須包含self引數, 且必須在第一個

    self引數無需顯式傳參, 在呼叫時可忽略

類資料成員 & 物件資料成員:

參考部落格:

https://zag666.blog.csdn.net/article/details/105209782

C++中, 類資料成員即為靜態資料成員, 需要使用static訪問, 而物件資料成員跟隨物件繫結

python中:

  • 直接定義在類中的資料成員為類資料成員

    image-20210110112814224

    但這個資料成員與C++的又有些不同, 他可以作為靜態資料成員, 被所有類例項訪問, 但若有類例項對其進行了修改, 則不會影響到其他類的訪問, 修改的類會建立自己的物件資料成員

    class my_class(object):
        value_list = [1, 2]
    
    
    if __name__ == '__main__':
    
        class1 = my_class()
        class2 = my_class()
    
        class2.value_list = [3, 4]
    
        print(my_class.value_list)
        print
    (class1.value_list) print(class2.value_list) print(id(my_class.value_list)) print(id(class1.value_list)) print(id(class2.value_list))
  • 使用self修飾的成員為物件資料成員:

    無需像C++一樣事先宣告, 直接在__init()__中定義即可, 其範圍不侷限與__init()__, 在整個類中均可使用, 並且可被外部訪問

繼承&派生:

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

幾個注意點:

  1. Python支援多繼承

    所以子類在使用基類的方法時, 若沒有顯式指定, 則將從左到右的從基類中搜索匹配的方法名

    如果基類中有重名方法名, 則需要注意這一點

    class people:
        #定義基本屬性
        name = ''
        age = 0
        #定義私有屬性,私有屬性在類外部無法直接進行訪問
        __weight = 0
    
        #定義構造方法
        def __init__(self, n, a, w):
            self.name = n
            self.age = a
            self.__weight = w
    
        def speak(self):
            print("%s 說: 我 %d 歲。" % (self.name, self.age))
            
            
    #單繼承示例
    class student(people):
        grade = ''
    
        def __init__(self, n, a, w, g):
            #呼叫父類的構函
            people.__init__(self, n, a, w)
            self.grade = g
    
        #覆寫父類的方法
        def speak(self):
            print("%s 說: 我 %d 歲了,我在讀 %d 年級" % (self.name, self.age, self.grade))
    
    
    #另一個類,多重繼承之前的準備
    class speaker():
        topic = ''
        name = ''
    
        def __init__(self, n, t):
            self.name = n
            self.topic = t
    
        def speak(self):
            print("我叫 %s,我是一個演說家,我演講的主題是 %s" % (self.name, self.topic))
    
    
    #多重繼承
    class sample(speaker, student):
        a = ''
    
        def __init__(self, n, a, w, g, t):
            student.__init__(self, n, a, w, g)
            speaker.__init__(self, n, t)
    
    
    if __name__ == '__main__':
    
        test = sample("Tim", 25, 80, 4, "Python")
        test.speak()
    
  2. 引用的基類必須與子類在同一個作用域, 即可以被子類訪問到

    若要引用其他模組中的類, 則可以使用.運算子

    class DerivedClassName(modname.BaseClassName):
    

方法過載(覆蓋):

與C++相似, 在子類中定義一個與基類相同名稱的方法會將基類中的方法覆蓋, 而後呼叫子類的該方法, 執行的便是子類中的定義

class Parent:        # 定義父類
   def myMethod(self):
      print ('呼叫父類方法')

class Child(Parent): # 定義子類
   def myMethod(self):
      print ('呼叫子類方法')

c = Child()          # 子類例項
c.myMethod()         # 子類呼叫重寫方法

類的專有方法:

這玩意算是每個類中隱式呼叫的方法, 過載之後相當於C++的運算子operator過載

__init__ 		# 建構函式,在生成物件時呼叫
__del__ 		# 解構函式,釋放物件時使用
__repr__ 		# 列印,轉換
__setitem__ 	# 按照索引賦值
__getitem__		# 按照索引獲取值
__len__			# 獲得長度
__cmp__			# 比較運算
__call__		# 函式呼叫
__add__			# 加運算
__sub__			# 減運算
__mul__			# 乘運算
__div__			# 除運算
__mod__			# 求餘運算
__pow__			# 乘方

例子:

class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __str__(self):
        return 'Vector (%d, %d)' % (self.a, self.b)

    def __add__(self, other):
        return Vector(self.a + other.a, self.b + other.b)


if __name__ == '__main__':

    v1 = Vector(2, 10)
    v2 = Vector(5, -2)
    print(v1 + v2)

Vector (7, 8)