1. 程式人生 > >python學習 day017打卡 類與類之間的關係

python學習 day017打卡 類與類之間的關係

本節主要的內容:

1.依賴關係

2.關聯關係,組合關係,聚合關係

3.繼承關係,self到底是什麼?

4.類中的特殊成員

 

一.類與類之間的依賴關係

在面向物件的世界中,類與類中存在以下關係:

1.依賴關係

2.關聯關係

3.組合關係

4.聚合關係

5.繼承關係

6.實現關係

由於python是一門弱型別程式語言,並且所有的物件之間其實都是多型關係,也就是說,所有的東西都可以當做物件來使用.

所以我們在寫程式碼的時候很容易形成以上關係.首先我們先看第一種,也就是這些關係中緊密程度最低的一個,依賴關係.

class DaXiang:
    def
open(self, bx): # 這裡是依賴關係. 想執行這個動作. 必須傳遞一個bx print("大象高高興興走到了冰箱的面向前") bx.kai() # 傳遞來的物件執行kai()動作 print("大象成功的打開了冰箱門") def zhuang(self): print("自己走進了冰箱") def close(self, bx): print("大象要關冰箱門了") bx.guan() class BingXiang: def kai(self):
print("我是冰箱. 我會開門 ") def guan(self): print("我是冰箱. 我會關門 ") bx1 = BingXiang() dx = DaXiang() dx.open(bx1) dx.zhuang() dx.close(bx1)

 

依賴關係其實就是在方法中給方法的引數傳遞一個物件,此時類與類之間的關係就是依賴關係,但是關係是最輕的

二.關聯關係,組合關係,聚合關係

這三種關係在程式碼上寫法是一樣的,但是,從含義上是不一樣的.

1.關聯關係:兩種事物必須是互相關聯的,但是在某些特殊情況下是可以更改和更換的.

2.聚合關係:屬於關聯關係中的一種特例,側重點事xxx和xxx聚合成xxx.各自有各自的宣告週期.比如電腦:電腦裡有CPU,

硬碟,記憶體等等.電腦壞了,CPU還是好的,還是完整的個體

3.組合關係.屬於關聯關係中的一種特例.寫法上差不多,組合關係比聚合關係還要緊密,比如人的大腦,心臟,各個器官,這些

器官組合成一個人.這時,這個人和他的器官是共同存在,共同消亡的.

 

關聯關係:

ass Boy:
    def __init__(self, name, girlFriend = None):
        self.name = name
        self.girlFriend = girlFriend # 關聯關係

    def chi(self): # b
        if self.girlFriend:
            self.girlFriend.happy()
            print("%s和%s在吃飯"  %  (self.name, self.girlFriend.name))
        else:
            print("沒女朋友吃什麼吃")

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

    def happy(self):
        print("有好吃的就開心")


b = Boy("王明")
g = Girl("肉絲")
# b物件的girlFriend賦值  g

b.girlFriend = g # 突然天降女朋友
b.chi()
b.girlFriend = None
b.c

 

關聯關係其實就是把另個類的物件作為這個類的物件作為這個類的屬性來傳遞和儲存.

 

組合關係和聚合關係,其實程式碼上的差別不大,都是把另一個類的物件作為這個類的屬性來傳遞和儲存.只是含義上會有些許的不同而已.

 

三.繼承關係

在面向物件的世界中存在著繼承關係.我們現實中也存在著這樣的關係.我們說過.x是一種y.這時理解層面上的.如果上升到程式碼層面.我們

可以這樣認為.子類在不影響父類的程式執行的基礎上對父類進行的擴充和擴充套件.這裡我們可以把父類稱為超類或者基類.子類被稱為派生類.

 

類名和物件預設是可以作為字典的key,即可雜湊的

class Foo:
     def __init__(self):
        pass
     def method(self):
        pass
    # 該類的物件就不可雜湊了
    #  __hash__ = None


print(hash(Foo)) # 類和物件預設都是可雜湊的
print(hash(Foo())) # unhashable type: 'Foo'

 

當在類中加入__hash__=None,物件就是不可雜湊的了

 

接下來繼續講繼承上的相關內容.

記住:不管方法之間如何進行呼叫,類與類之間是如何關係,預設的self都是訪問這個方法的物件

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

 

 

 

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

結論:self就是你訪問的那個物件.先找自己,然後在找父類的.

 

四.類中的特殊成員

特殊成員:類中方法名左右兩邊帶雙下劃線的成員

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 物件就不可雜湊了.

....

class Car:
    def __init__(self, color, pai):
        self.color = color
        self.pai = pai
    def __call__(self, *args, **kwargs):
        print("這裡是call")

    def __getitem__(self, item):
        print("這裡是getitem, item=", item)

    def __setitem__(self, key, value):
        print(key, value)

    def __delitem__(self, key):
        print(key)

    def __add__(self, other): # 在執行兩個物件相加的時候自動呼叫
        print("證明我來過")
    def __enter__(self):
        print("進來的時候")
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("這裡是出去")

    def __str__(self): # 當前物件的字串表示形式
        return "我的車很厲害"

    def __repr__(self):  #  一個物件的官方字串表示形式
        return "我的車非常非常厲害"

    def __iter__(self):
        return (i for i in range(10))

    # def __hash__(self):
    #     return hash(self.pai) + hash(self.color)
    __hash__ = None


c = Car("", "1.5T") # 在建立物件的時候會自動的呼叫__init__()  類名()  ==> init()
# c() # 物件()  => __call__()
# c["馬化騰"] # 物件[任意引數] => __getitem__(item)
# c["胡辣湯"] = "河南開封"
# del c['上海小混沌大碗']

# c2 = Car("黑色", "1.8T")
# cc = c+c2

# with c as m: # 裝飾器
#     print("哈哈哈")
#
# print("呵呵呵")
# print(c) # 當列印一個物件的時候. 預設的去執行__str__ 根據__str__返回的結果進行列印
# print(repr(c))

print("%s" % c) # %s __str__
print("%r" % c) # %r __repr__

# c > c2 # great than
# c< c2  # less than
# c >= c2 # greate and equals

for s in c:
    print(s)

 

 

建立物件的真正步驟:

首先,在執行類名()的時候.系統會自動先執行__new__()來開闢記憶體.此時新開闢出來的記憶體區域是空的.

緊隨其後,系統自動調動__init__() 來完成物件的初始化工作.按照時間軸來算.

 

1.載入類

2.開闢記憶體(__new__)

3.初識化(__init__)

4.使用物件幹xxx

class Car:
    def __init__(self, color, pai): # 初始化方法
        print("哪有地呀")
        self.color = color
        self.pai = pai

    # 這裡才是真正的構造方法
    def __new__(cls, *args, **kwargs):
        print("我的天哪")
        # 固定的返回值
        return object.__new__(cls)

c = Car("紅色", "京A66666") # 先執行__new__ 返回object.__new__(cls).把返回的空物件傳遞給 __init__()

print(c.color)