1. 程式人生 > >Python 16 類與類之間的關係

Python 16 類與類之間的關係

類與類之間的關係

類與類之間的關係
類與類中存在的關係:
1.依賴關係
2.關聯關係
3.組合關係
4.聚合關係
5.繼承關係
6.實現關係

python是一門弱型別程式語言,並且所有的物件之間其實都是多型關係,所有的東西都可以當做物件來使用。
一.依賴關係
依賴關係:我需要用你,但你不屬於我,這種關係是最弱的。

例:把大象裝進冰箱,建立大象、冰箱兩個類
class Elephant:
def init(self,name):
self.name = name

def open(self,ref):
    print('大象說:開門吧')
    ref.open_door()

def close(self,ref):
    print('大象說:關門吧')
    ref.close_door()

def take(self):
    print('大象走進冰箱')

class BingXiang:
def open_door(self):
print('冰箱:門開了')

def close_door(self):
    print('冰箱:關好了')

r = BingXiang() # 造冰箱

el = Elephant('獨立自主的大象') # 造大象
el.open(r) # 把冰箱當作引數傳遞進大象的類中,大象可以指定任何一個冰箱去進行操作
el.take()
el.close(r)
二.關聯關係、組合關係、聚合關係
1.關聯關係:兩種事物必須是相互關聯的,但是在某些特殊情況下是可以更改的和更換的。

2.聚合關係:屬於關聯關係中的一種特例,重點是xxx和xxx聚合城了xxx,各自有各自的宣告週期,主體完蛋了,個體依然存在。

3.組合關係:屬於關聯關係中的一種特例,寫法上差不多,組合關係比聚合關係還要緊密,主體完蛋了,個體跟著一起完蛋。

例:
男女朋友關係,可以是相互的也可以是單方面的
class Boy:
def init(self,name,girlFriend = None):
self.name = name
self.girlFriend = girlFriend

    def yujian(self):
        if self.girlFriend:
            print('%s 和 %s 在一起吃飯' % (self.name,self.girlFriend.name))
        else:
            print('單身狗吃什麼飯')

class Girl:
    def __init__(self,name):
        self.name = name

b = Boy('alex')
b.yujian()

g = Girl('王婆')
b.girlFriend = g  # 有女朋友了
b.yujian()        # 兩個人一起吃飯

注:關聯關係在邏輯上出現了,我需要你,你還要屬於我,這種邏輯就是關聯關係。
組合關係和聚合關係,程式碼上的差別不大,都是把另一類的物件作為這個類的屬性來傳遞和儲存,只是在含以上有不同。
三:繼承關係
繼承關係:子類在不影響父類的程式執行的基礎上對父類進行擴充和擴充套件,我們可以父類成為超類或者基類,子類被稱為派生類。

例:類名和物件預設是可以作為字典的key的

    class Foo:
        def __init__(self):
            pass
        def method(self):
            pass
    
    print(hash(Foo))
    print(hash(Foo()))
     # 既然可hash,那就說明字典的key可以是物件或者類
    
    dic = {}
    dic[Foo] = 123
    dic[Foo()] = 456
    print(dic)  # {<class '__main__.Foo'>: 123, <__main__.Foo object at 0x00000000021D82E8>: 456}

四:self
接下來研究繼承上的相關內容,主要研究self(不關方法之間如何進行呼叫,類與類之間是何關係,
預設的self都是訪問這個方法的物件)

例1:

    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
             print(self.num)
    class Foo(Base):
         pass
         
    obj = Foo(123)
    obj.func1()    # 123 執行的Base中的func1

例2:

    class Base:
        def __init__(self, num):
            self.num = num
            
        def func1(self):
             print(self.num)

    class Foo(Base):
        def func1(self):
         print("Foo. func1", self.num)

    obj = Foo(123)
    obj.func1() # Foo. func1 123 運⾏的是Foo中的func1

總結:self在訪問方法的順序:永遠都是先找自己,自己找不到再到父類裡找。

例3:

    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
             print(self.num)
             self.func2()
        def func2(self):
             print(111, self.num)
    class Foo(Base):
        def func2(self):
            print(222, self.num)

    lst = [Base(1), Base(2), Foo(3)]
    for obj in lst:
    obj.func2()   # 111 1 | 111 2 | 222 3

例4:

    class Base:
        def __init__(self, num):
            self.num = num
        def func1(self):
            print(self.num)
            self.func2()
        def func2(self):
            print(111, self.num)

    class Foo(Base):
        def func2(self):
            print(222, self.num)

    lst = [Base(1), Base(2), Foo(3)]
    for obj in lst:
        obj.func1()  # 1  111  1  |  2  111  2  |  3  222  3

總結:self就是你訪問方法的那個物件,先找自己的,然後在找父類的。
五:類中的特殊成員
像__init__()這樣,帶上下劃線的方法就屬於特殊成員,在特殊的場景會被自動執行。

例:

  1. 類名() 會自動執行__init__()
  2. 物件() 會自動執行__call__()
  3. 物件[key] 會自動執行__getitem__()
  4. 物件[key] = value 會自動執行__setitem__()
  5. del 物件[key] 會自動執行 delitem()
  6. 物件+物件 會自動執行 add()
  7. with 物件 as 變數 會自動執行__enter__ 和__exit__
  8. 列印物件的 時候 會自動執行 str
  9. 幹掉可雜湊 hash == None 物件就不可雜湊了.

建立物件的真正步驟:
首先, 在執行類名()的時候,系統會自動先執⾏__new__()來開闢記憶體,此時新開闢出來的記憶體區域是空的。
緊隨其後系統⾃自動呼叫__init__()來完成物件的初始化操作,按照時間軸來算。
1.載入類
2.開闢記憶體(new)
3.初始化(init)
4.使用物件去執行什麼