01 - 面向對象 - 繼承簡介
1.提高了代碼的複用性 2.讓類與類之間產生關係,有了這個關係,纔有了多態的特性
class Person():
name = ''
age = ''
class Doctor():
name = ''
age = ''
def zhibing(self):
print('治療病人')
class soldier():
name = ''
age = ''
def baowei(self):
print('保衛國家')
1.繼承的簡介
1.提高了代碼的複用性 2.讓類與類之間產生關係,有了這個關係,纔有了多態的特性
3.繼承也是面向對象的三大特徵之一
定義一個動物類
如何能讓這個當前的動物類實現全部的功能
1.直接修改這個動物類,在這個類中添加我們需要的功能
2.可以直接創建一個新類
3.直接從動物類中繼承它的屬性和方法
在創建類的時候,如果我們省略父類則默認父類爲object
所有類都繼承object,object是所有類的父類
class Animal:
def run(self):
print('動物在跑')
def sleep(self):
print('動物在睡覺')
# def speak(self):
# print('動物會叫')
class cat():
def run(self):
print('貓在跑')
def sleep(self):
print('貓在睡覺')
def speak(self):
print('貓在叫')
class cat(Animal):
def run(self):
print('貓在跑')
def speak(self):
print('喵喵喵')
# a = Animal()
c = cat()
# print(c)
c.run()
# c.sleep()
# c.speak()
# r = isinstance(c,Animal)
# issubclass()
class Person():
pass
print(issubclass(cat,Animal))
print(issubclass(Animal,object))
print(issubclass(Person,object))
# print(issubclass(print,object)) # 不能這麼寫
print(isinstance(print,object))
>>>
貓在跑
True
True
True
True
2. - 面向對象 - 重寫
class Animal:
def run(self):
print('動物在跑')
def sleep(self):
print('動物在睡覺')
# def speak(self):
# print('動物會叫')
class cat():
def run(self):
print('貓在跑')
def sleep(self):
print('貓在睡覺')
def speak(self):
print('貓在叫')
# 如果子類中有父類同名的方法,則通過子類的實例去調用該方法時, 會調用子類的方法而不是父類的方法,這個特點也稱之爲我們所說的方法重寫(覆蓋)
class cat(Animal):
# def run(self):
#
# print('貓在跑')
def speak(self):
print('喵喵喵')
# a = Animal()
c = cat()
# print(c)
# c.run()
# c.sleep()
# c.speak()
# 當我們調用一個對象的方法時
# 會優先去當前對象中去尋找是否有該方法,如果有則直接調用
# 如果沒有,則去當前對象的父類中尋找,如果父類中有則直接調用
# 如果沒有,則去父類對象中的父類中去尋找,以此類推,直到找到object,如果沒有則報錯
class A(object):
def text(self):
print('AAA')
class B(A):
def text(self):
print('BBB')
class C(B):
def text(self):
print('CCC')
c = C()
c.text()
>>>
CCC
03.面向對象 - supper()
class Animal:
def __init__(self,name):
self._name = name
def run(self):
print('動物在跑')
def sleep(self):
print('動物在睡覺')
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
# 三、supper()
# 父類中的所有方法都會被子類繼承,包括特殊方法
class cat(Animal):
# 我希望可以直接調用父類中的__init__方法來初始化父類中的屬性
# supper()可以獲得當前類的父類
# 通過supper()返回對象調應父類方法時,不需要傳遞self
def __init__(self,name,age):
Animal.__init__(self,name) # 或者 supper().__init__(name)
# self._name = name
self._age = age
def run(self):
print('貓在跑')
def speak(self):
print('喵喵喵')
@property
def age(self):
return self._age
@age.setter
def age(self, age):
self._age = age
c = cat('波斯貓',44)
c.name = '加菲貓'
print(c.name)
print(c.age)
>>>
加菲貓
44
04 - 面向對象 - 多重繼承
Python中支持多重繼承,也就是我們可以爲一個類同時制定多個父類
bases
語法 類名 .__bases__可以獲取當前類所有的父類
class A(object):
def text(self):
print('AAA')
class B(object):
def text(self):
print('BBB')
class C(B):
pass
print(C.__bases__) # 打印結果是一個元組 打印結果:(<class '__main__.B'>,)
print(B.__bases__) # 打印結果是一個元組 打印結果:(<class 'object'>,)
class A(object):
def text(self):
print('AAA')
class B(object):
def text(self):
print('BBB')
class C(A,B):
pass
print(C.__bases__) #打印結果是兩個元組 打印結果:(<class '__main__.A'>, <class '__main__.B'>)
# 我們在開發的時候儘量不要用多重繼承,原因是增加我們代碼的複雜程度
# 如果多個父類中出現重名的方法,則會先在第一個父類中尋找,然後再找第二個,再找第三個,後邊會覆蓋前邊
class A(object):
def text(self):
print('AAA')
class B(object):
def text2(self):
print('BBB')
class C(A,B):
pass
c = C()
c.text() # AAA
c.text2() # BBB
# 05. - 多態
多態也是面向對象的三大特性之一
一個對象可以以不同的邢臺去呈現
鴨子類型:
如果有一個東西 走路像鴨子 ,叫聲像鴨子,那麼它就是鴨子
```python
class A:
def __init__(self,name):
self._nmae = name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
class B:
def __init__(self, name):
self._nmae = name
def __len__(self):
return 10
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
class C:
pass
a = A('葫蘆娃')
b = B('鋼鐵俠')
c = C()
def say(obj):
print('你好 %s'%obj.name)
def say2(obj):
# 做類型檢查
# 違反了多態的函數只適用於一種類型的對象,無法處理其他誒行的對象,這樣會導致函數的適用性非常差
if isinstance(obj,A):
print('你好 %s'%obj.name)
# say(c)
# say2(b) # Process finished with exit code 0
# len()
# 之所以一個對象能夠通過len()函數獲取長度,是因爲對象中具有一個特殊方法__len__
lst = [1,2,3]
s = 'Python'
# print(len(lst))
# print(len(s))
print(len(b)) # 10
print(len(c)) # TypeError: object of type 'C' has no len()
# c這個對象沒有len()這個函數
# 面相對象的三大 特徵 : 封裝:確保對象中數據的安全 繼承;保證了對象的可擴展 多態:保證了程序的靈活性
06. - 面向對象 - 屬性和方法
# 類方法和實例方法的區別:實例方法第一個參數是self,類方法第一個參數是cls
class A(object):
# 類屬性 直接在類中第一個屬性就是類屬性
# 類屬性可以通過類本身或者是類的實例訪問
# 類屬性 只能通過類對象來修改,無法通過實例對象來修改
count = 0
# 實例屬性,通過實例對象添加的屬性叫做實例屬性
# 實例屬性 只能通過實例對象來訪問和修改,類對象無法訪問和修改
def __init__(self):
self.name = '葫蘆娃'
# 實例方法
# 在類中定義,以self爲參數的方法都是實例方法
# 實例方法在調用時,Python會將調用的對象作爲self傳入
#當通過類調用時,不會自動傳入self
def text(self):
print('這是text方法',self)
# 類方法
# 在類的內部使用 @classmethod 來修飾的方法叫做類方法
# 類方法第一個參數是cls 會被自動上傳 cls就是當前的類對象
@classmethod
def text2(cls):
print('這是text2方法',cls)
print(cls.count)
# 靜態方法
# 在類中內部使用@staticmethod 來修飾的方法屬於靜態方法
# 靜態方法不需要指定任何默認的參數,靜態方法可以通過類和實例去調用
@staticmethod
def text3():
print('text3執行了')
a = A()
# a.count = 5
# A.count = 5
# print('A',A.name) # AttributeError: type object 'A' has no attribute 'name'
print('a',a.name) # a 葫蘆娃
a.text() # 這是text方法 <__main__.A object at 0x000001E4EA0C0BE0>
A.text(a) # 這是text方法 <__main__.A object at 0x000001E4EA0C0BE0> # a.text() 等價於 A.text(a)
A.text2() # 這是text2方法 <class '__main__.A'>
# 0
a.text2() # 這是text2方法 <class '__main__.A'> # A.text2() 等價於 a.text2()
# 0
A.text3() # text3執行了
a.text3() # text3執行了