在面向對象中,類和類之間也能夠產生相關的關係
類中的關係: 依賴關係是最輕的,最重的是繼承關係,關聯關係是比較微妙的
依賴關係
執行某個動做的時候,須要xxx來幫助完成這個操做,此時的關係是最輕的.
隨時能夠更換另一個東西來完成此操做程序員
1 class Person: 2 def f1(self,tools): # 經過參數的傳遞把另一個類的對象傳遞進來 3 tools.run() 4 print('皮一下很開心') 5 class Computer: 6 def run(self): 7 print('電腦開機運行') 8 class Phone: 9 def run(self): 10 print('手機開機') 11 c = Computer() 12 a = Phone() 13 p = Person() 14 p.f1(a) #把Phone類的對象a傳遞給Person的f1方法做爲參數 15 結果 16 手機開機 17 皮一下很開心 18 19 事例二 20 植物大戰殭屍 21 class Plant: 22 def __init__(self,hp,ad): 23 self.hp = hp 24 self.ad = ad 25 def attack(self,js): 26 print('植物攻擊殭屍') 27 js.hp -= self.ad 28 print(f'殭屍掉血{self.ad},剩餘{js.hp}') 29 class JiangShi: 30 def __init__(self,hp,ad): 31 self.hp = hp 32 self.ad = ad 33 def attack(self,zw): 34 print('殭屍咬植物') 35 zw.hp -= self.ad 36 print(f'植物掉血{self.ad},剩餘{zw.hp}') 37 zw = Plant(100,11) 38 js = JiangShi(80,15) 39 zw.attack(js) 40 zw.attack(js) 41 js.attack(zw) 42 js.attack(zw) 43 結果 44 植物攻擊殭屍 45 殭屍掉血11,剩餘69 46 植物攻擊殭屍 47 殭屍掉血11,剩餘58 48 殭屍咬植物 49 植物掉血15,剩餘85 50 殭屍咬植物 51 植物掉血15,剩餘70
關聯關係
對象裏面包含對象app
1 一對一關係 2 class Boy: 3 def __init__(self,name,girFriend=None): 4 self.name = name 5 self.girFriend = girFriend 6 def play(self): 7 if self.girFriend: 8 print(f'{self.name}帶着他女友{self.girFriend.name}去吃飯') 9 else: 10 print('單身狗,還吃什麼飯') 11 def movie(self): 12 if self.girFriend: 13 print(f'{self.name}帶着他女友{self.girFriend.name}去看電影') 14 else: 15 print('單身狗,還看什麼電影') 16 class Girl: 17 def __init__(self,name): 18 self.name = name 19 b = Boy('劉昊然') 20 g = Girl('劉麗') 21 b.play() 22 23 b.girFriend = g 24 b.play() 25 26 g2 = Girl('王萌') 27 b.girFriend = g2 28 b.movie() 29 30 31 一對多關係 32 self.teach_list = [t1,t2,...] 33 class School: 34 def __init__(self,name): 35 self.teach_list = [] 36 def zhaopin(self,teach): 37 self.teach_list.append(teach) 38 def shangke(self): 39 for i in self.teach_list: 40 i.work() 41 class Teacher: 42 def __init__(self,name): 43 self.name = name 44 def work(self): 45 print(f'{self.name}在上課') 46 lnh = School('測試') 47 t1 = Teacher('趙老師') 48 t2 = Teacher('劉老師') 49 lnh.zhaopin(t1) 50 lnh.zhaopin(t2) 51 lnh.shangke() 52 結果 53 趙老師在上課 54 劉老師在上課
繼承關係函數
1 class Base: #父類又叫基類又叫超類 2 def chi(self): 3 print('吃飯') 4 class Foo(Base): #子類又叫派生類,這個類繼承了Base類,Foo類是對Base的一個擴展 5 def he(self): 6 print('喝水') 7 f = Foo() 8 f.chi() 9 f.he() 10 print(hash(Foo)) #默認類和建立的對象都是可哈希的 11 print(hash(Foo())) 12 結果 13 吃飯 14 喝水 15 -9223371912599947772 16 -9223371912597968945 17 18 去掉可哈希 19 __hash__ = None 20 class Base: 21 def chi(self): 22 print('吃飯') 23 class Foo(Base): 24 __hash__ = None # 當前類的對象不可哈希 25 def he(self): 26 print('喝水') 27 f = Foo() 28 f.chi() 29 f.he() 30 print(hash(Foo)) # 類名永遠可哈希 31 print(hash(Foo())) # TypeError: unhashable type: 'Foo'
類名至關於變量名測試
1 class Foo: 2 def chi(self,food): 3 print('吃魚和',food) 4 class Bar: 5 def chi(self,food): 6 print('吃肉和',food) 7 dic = {Foo:'麪包',Bar:'牛奶'} 8 for k,v in dic.items(): 9 k().chi(v) 10 結果 11 吃魚和 麪包 12 吃肉和 牛奶
練習spa
1 事例1 2 class Base: 3 def __init__(self, num): 4 self.num = num 5 6 def func1(self): 7 print(self.num) 8 self.func2() 9 10 def func2(self): 11 print(111, self.num) 12 13 class Foo(Base): 14 def func2(self): 15 print(222, self.num) 16 17 lst = [Base(1), Base(2), Foo(3)] 18 for obj in lst: 19 obj.func2() 20 結果 21 111 1 22 111 2 23 222 3 24 25 事例2 26 class Base: 27 def __init__(self, num): 28 self.num = num 29 def func1(self): 30 print(self.num) 31 self.func2() 32 def func2(self): 33 print(111, self.num) 34 35 class Foo(Base): 36 def func2(self): 37 print(222, self.num) 38 39 lst = [Base(1), Base(2), Foo(3)] 40 for obj in lst: 41 obj.func1() 42 結果 43 1 44 111 1 45 2 46 111 2 47 3 48 222 3
self:誰調用的就是誰,類型是根據調用方的對象來進行變換的
super:表示的是父類
特殊成員:
__init__() # 建立對象的時候初始化操做
__call__() # 對象()
__getitem__() # 對象[哈哈]
__setitem__() # 對象[哈哈] = 值
__new__() # 建立對象的時候.開闢內存
__hash__() # 可哈希 hash()code
1 __call__ 2 對象後面加括號,觸發執行 3 注:構造方法的執行是由建立對象觸發的,即:對象 = 類名() ;而對於 __call__ 方法的執行是由對象後加括號觸發的,即:對象() 或者 類()() 4 class Foo: 5 def __init__(self): 6 pass 7 8 def __call__(self, *args, **kwargs): 9 print('__call__') 10 11 obj = Foo() # 執行 __init__ 12 obj() # 執行 __call__ 13 結果 14 __call__ 15 16 事例2 17 class Foo: 18 def __init__(self): # 初始化操做 19 print('我是init,我是第二') 20 21 def __new__(cls, *args, **kwargs): # 建立,是真正的構造方法,能夠開闢內存 22 print('我是new,我是第一') 23 return object.__new__(cls) 24 25 def __call__(self, *args, **kwargs): # 對象() 26 print('我是對象call') 27 28 def __getitem__(self, item): # 對象[] 29 print('item',item) 30 print('我是getite') 31 32 def __setitem__(self, key, value): # 對象[key] = value 33 print('key',key) 34 print('value',value) 35 Foo() 36 f = Foo() # 自動執行__init__() 37 f() # 調用__call__() 38 print(callable(f)) # 對象() 39 print(f['娃哈哈']) #自動調用__getitem__() 40 f['人']='劉麗' #自動的調用__getitem__() 41 結果 42 我是new,我是第一 43 我是init,我是第二 44 我是new,我是第一 45 我是init,我是第二 46 我是對象call 47 True 48 item 娃哈哈 49 我是getite 50 None 51 key 人 52 value 劉麗 53 54 55 事例3 56 class Foo: 57 def __init__(self,name): 58 self.name=name 59 60 def __getitem__(self, item): 61 print(self.__dict__[item]) 62 63 def __setitem__(self, key, value): 64 self.__dict__[key]=value 65 def __delitem__(self, key): 66 print('del obj[key]時,我執行') 67 self.__dict__.pop(key) 68 def __delattr__(self, item): 69 print('del obj.key時,我執行') 70 self.__dict__.pop(item) 71 72 f1=Foo('sb') 73 f1['age']=18 74 f1['age1']=19 75 print(f1.__dict__) 76 del f1.age1 77 del f1['age'] 78 f1['name']='alex' 79 print(f1.__dict__) 80 結果 81 {'name': 'sb', 'age': 18, 'age1': 19} 82 del obj.key時,我執行 83 del obj[key]時,我執行 84 {'name': 'alex'} 85 86 87 事例4 88 class Person: 89 def __init__(self,name,age): 90 self.name = name 91 self.age = age 92 #這個對象字符串的表示 93 def __str__(self): #返回該對象的字符串表示形式 94 return f'{self.name},{self.age}' 95 def __repr__(self): #該對象的官方的字符串表示形式 96 return f'{self.name},{self.age}' 97 s = Person('bob','18') 98 print(s) 99 結果 100 bob,18 101 102 事例5 103 class B: 104 def __str__(self): 105 return 'str : class B' 106 def __repr__(self): 107 return 'repr : class B' 108 b = B() 109 print('%s' % b) #這個執行的是__str__函數方法 110 print('%r' % b) #這個執行的是__repr__函數方法 111 結果 112 str : class B 113 repr : class B 114 115 116 __del__ 117 析構方法,當對象在內存中被釋放時,自動觸發執行 118 注:此方法通常無須定義,由於Python是一門高級語言,程序員在使用時無需關心內存的分配和釋放,由於此工做都是交給Python解釋器來執行,因此,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。 119 class Foo: 120 121 def __del__(self): 122 print('執行我啦') 123 124 f1=Foo() 125 del f1 126 print('------->') 127 結果 128 執行我啦 129 ------->