面向物件-靜態於動態方法,繼承
阿新 • • 發佈:2022-04-07
目錄
動態方法於靜態方法
# 動態方法 1.繫結給物件的方法 class Student: def run(self): print(self) # 類呼叫繫結給物件的方法,有幾個引數就需要傳及格引數 Student.run(123) #物件呼叫繫結給物件的方法會自動將物件當作第一個引數傳入 obj1.run() 2.繫結給類的方法,會自動將類當作第一個引數傳入 class Student: @classmethod def eat(cls): prtin(cls) # 類呼叫繫結給類的方法,會自動將類作為第一個引數傳入 print(Student) # <class '__main__.Student'> Student.eat() # <class '__main__.Student'> # 物件呼叫繫結給類的方法也不要傳參,會將產生該物件的類自動當作第一個引數傳入 obj1.eat() # <class '__main__.Student'> # 靜態方法 class Student: @staticmethod def speak(a): print(a) 1.普普通通的函式,無論誰呼叫,都必須傳固定的引數個數 # 類呼叫靜態方法要自己傳值 Student.speak(111) #物件呼叫靜態方法也要自己傳值 object.speak(111)
面向物件三大特徵之一:繼承
''' 面向物件三大特徵:繼承、封裝、多型 其中最重要的就是繼承 ''' # 繼承的含義 現實生活中繼承是用來描述人與人之間資源的從屬關係 eg:兒子繼承父親的產業 面向物件中繼承則是用來描述類魚類之間資料的從屬關係 eg:類A繼承了類B 那麼類A就可以使用類B中的資料和功能 # 繼承的目的 現實生活中通過繼承,可以快速積累資源,少奮鬥很多年,並且可以多繼承 面向物件中可以通過繼承減少程式碼冗餘 提升開發效率 同樣也支援多繼承 # 繼承的基本使用 class a(b): pass 我們將被繼承的類稱為父類:b 繼承別人的類稱為子類:a class a(b,v,d): pass 在python中可以同時繼承多個父類
繼承的本質
抽象:由下往上抽取相同的特徵 繼承:由上往下繼承資料功能 ''' 在面向物件程式設計過程中 其實類和父類的主要功能都是減少程式碼冗餘 物件:資料於功能的結合體 類:多個物件相同資料功能的結合體 父類:多個類相同資料和功能的結合體 ''' 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('tom', 18, 'male')
名字的查詢順序
# 不繼承的情況下
名字的查詢順序
先從物件自己的名稱空間中查詢 沒有則去類裡面的名稱空間查詢
1.物件 ==> 2.類
'''注意:設定值的情況下實在滋生的名稱空間中新增或者修改資料'''
# 單繼承的情況下
名字查詢順序
先從物件自己的名稱空間中查詢 沒走就去產生物件的類中查詢,在沒有,就去父類裡面查詢
1.物件 ==》 2.生成物件的類 ==》 3.父類
經典案例
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__ # 空的(在python2中)
# print(A.__bases__) # (<class 'object'>,)在python3中
"""
有時候我們在定義類的時候會習慣性的寫
class MyClass(object):
pass
為了相容python2和python3
"""
強調:研究菱形和非菱形問題object不參與影象構建
非菱形繼承的情況下
父類名字查詢順序按照從左到右一次查詢,如果多個父類還有分類‘深度優先’(也就是查詢先父類的父類,在查詢別的父類)
菱形繼承的情況下
父類中名字的查詢順序就是按照繼承是從左到右依次查詢,如果多個父類還有分類 那麼遵循‘廣度優先’(從左到右,一次查詢,父類,最後在查詢父類的父類)
### 名字查詢順序永遠是從當前物件自身開始查詢
派生類
'''當一個類,想要在父類的基礎上新增新的屬性的時候,可以使用super方法來達成目的,,而這個類就是父類的派生類(相當於子類,只是在父類的基礎上新增額外的東西)'''
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
class Student(Person):
def __init__(self, name, age, gender):
# super(Person, self).__init__(name, age) # 子類呼叫父類的語法,完整版
super().__init__(name, age) # 子類呼叫父類的語法,精簡版
self.gender = gender
'''
如果自己寫的子類需要使用父類的方法 並且還需要基於該方法做擴充套件
這樣的子類我們稱之為派生類(本質還是子類)
那麼可以使用super關鍵字來實現
'''
s1 = Student('kevin', 28, 'female')
print(s1.__dict__) # {'name': 'kevin', 'age': 28, 'gender': 'female'}
派生功能前瞻
class MyClass(list):
def append(self,args):
if args == 123:
print('數字123不能追加')
return
super(MyClass, self).append(args)
obj1 = MyClass()
obj1.append(333)
obj1.append(222)
obj1.append(123)
print(obj1)