面向物件(2)
阿新 • • 發佈:2022-04-07
-
動態方法與靜態方法
-
-
屬性查詢
-
派生類
-
派生功能前瞻
動態方法與靜態方法
# 動態方法
1.繫結給物件的方法
class Student:
def run (self):
print(self)
# 類呼叫繫結給物件的方法:有幾個引數就需要傳幾個引數
Student.run(123)
# 物件呼叫繫結給物件的方法:會自動將物件當作第一個引數傳入
obj1.run()
2.繫結給類的方法
class Student:
面向物件的三大特性之一:傳承
"""
面向物件的三大性 其中最重要的就是繼承
繼承、封裝、多型
"""
# 繼承的含義
現實生活中繼承是用來描述人與人之間資源的從屬關係
eg:兒子繼承父親 那麼就可以擁有父親的一切
面向物件中繼承則是用來描述類與類之間的資料的從屬關係
eg:類A繼承了類B 那麼類A就可以使用類B中所有的資料(資料、功能...)
# 繼承的目的
面向物件中通過繼承可以減少程式碼冗餘 提升開發效率 同樣也支援多繼承
eg:類A可以繼承多個類同時擁有多個類裡面的程式碼使用權
# 繼承的基本使用
"""
class A(B):
pass
我們將被繼承的類稱為:父類或者基類 B
繼承別人的類稱為:子類或者派生類 A
"""
在python中一個類可以同時繼承多個父類
class A(B,C,D):
pass
繼承的本質
抽象:右下往上抽取相同特徵
繼承:由上往下直接白嫖資源
"""
在面向物件程式設計中 其實和父類的主要功能都是用來減少程式碼冗餘的
物件:資料與功能的結合體
類:多個相同資料和功能的結合體
父類:多個類相同資料和功能的結合體
"""
class Person:
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
class Teacher(Person):
def teach(self):
print(f'{self.name}老師正在講課')
class Student(Person):
def study(self):
print(f'{self.name}學生正在聽課')
stu1 = Student('faker',28,'male')
名字的查詢順序
# 不繼承的情況下
名字的查詢順序是
先對物件自己的名稱空間中查詢 沒有則去類裡面的名稱空間查詢
物件 >>> 類
'''注意設定值的情況是在自身的名稱空間中新增或者修改資料'''
# 單繼承的情況下
名字的查詢順序是
先從物件自己的名稱空間中查詢 沒有則取產生物件的類中查詢
如果還沒有並且類有父類則取父類中查詢 以此往復下去!!!
物件 >>>類 >>>父類
經典案例
class A:
def f1(self):
print('from A.f1')
def f2(self):
print('from A.f2')
self.f1() '''以後看到self點東西 一定要問自己self是誰'''
class MyClass(A):
def f1(self):
print('from MyClass.f1')
obj = MyClass()
obj.f2()
# 執行的方法分別是A裡面的f2和MyClass裡面的f1
# 多繼承的情況下
"""
在python2中存在經典類與新式類
在python3中只有新式類
區分的關鍵在於是否繼承了預設的object類
新式類:直接或者間接繼承的了object或者其子類的類
經典類:不繼承任何類
"""
class A:
pass
# print A.__bases__ # 空的
# print(A.__bases__) # (<class 'object'>,)
"""
有時候我們在定義類的時候會習慣的寫
class MyClass(object):
pass
為了相容python2和python3
"""
強度:研究菱形和非菱形問題object不參與圖形構建
非菱形繼承的情況下
父類中名字的查詢順序就是按照繼承時從做往右依次查詢
如果多個父類 那麼遵循"深度優先"
ADBECF
菱形繼承的情況下
父類中名字的查詢順序就是按照繼承時從左往右依次查詢
如果多個父類還有分類 那麼遵循"廣度優先"
ADBCFM
'''名字的查詢順序永遠都是 先從當前物件自身開始查詢'''
派生類
class Person:
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
class Teacher(Person):
def __init__(self,name,age,gender,level,salary):
# 用了Person類裡面的__init__方法之後
# super(Teacher,self).__init__(name,age,gender) # 子類呼叫父類的的方法 完整語法
super().__init__(name,age,gender) # 子類呼叫父類的方法 精簡語法
# 自己還要新增一個額外的東西
self.level = level
self.salary = salary
class Student(Person):
def __init__(self,name,age,gender,stu_id,class_id):
# 用了Person類裡面的__init__方法之後
super().__init__(name,age,gender)
# 自己還要新增一個額外的東西
self.stu_id = stu_id
self.class_id = class_id
"""
如果自己寫的子類需要使用父類的方法 並且還需要基於該方法做擴充套件
這樣的子類我們稱之為派生類(本質還是子類)
那麼可以使用super關鍵字來實現
"""
t1 = Teacher('faker',28,'male','特級',888888)
s1 = Student('kevin',78,'female',20191010,3)
print(t1.__dict__)
print(s1.__dict__)
派生功能前瞻
class MyClass(list):
def append(self,args):
if args == 123:
print('數字123不能追加')
return
super(MyClass,self).append(args)
obj1 = MyClass()
obj1.append(666)
obj1.append(777)
obj1.append(123)
print(obj1)