日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

day 17python 面对对象之继承

發布時間:2023/12/1 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 day 17python 面对对象之继承 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:什么面向對象的繼承?

比較官方的說法就是:

繼承(英語:inheritance)是面向對象軟件技術當中的一個概念。如果一個類別A“繼承自”另一個類別B,就把這個A稱為“B的子類別”,而把B稱為“A的父類別”也可以稱“B是A的超類”。繼承可以使得子類別具有父類別的各種屬性和方法,而不需要再次編寫相同的代碼。在令子類別繼承父類別的同時,可以重新定義某些屬性,并重寫某些方法,即覆蓋父類別的原有屬性和方法,使其獲得與父類別不同的功能。另外,為子類別追加新的屬性和方法也是常見的做法。 一般靜態的面向對象編程語言,繼承屬于靜態的,意即在子類別的行為在編譯期就已經決定,無法在執行期擴充。

字面意思就是:子承父業,合法繼承家產,就是如果你是獨生子,而且你也很孝順,不出意外,你會繼承你父母所有家產,他們的所有財產都會由你使用(敗家子兒除外)。

那么用一個例子來看一下繼承:

class Person:
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex

class Cat:
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex

class Dog:
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex

# 繼承的用法:
class Aniaml(object):
def __init__(self,name,sex,age):
self.name = name
self.age = age
self.sex = sex


class Person(Aniaml):
pass

class Cat(Aniaml):
pass

class Dog(Aniaml):
pass

class Person:def __init__(self,name,sex,age):self.name = nameself.age = ageself.sex = sexclass Cat:def __init__(self,name,sex,age):self.name = nameself.age = ageself.sex = sexclass Dog:def __init__(self,name,sex,age):self.name = nameself.age = ageself.sex = sex# 繼承的用法: class Aniaml(object):def __init__(self,name,sex,age):self.name = nameself.age = ageself.sex = sexclass Person(Aniaml):passclass Cat(Aniaml):passclass Dog(Aniaml):pass

繼承的有點也是顯而易見的:

1,增加了類的耦合性(耦合性不宜多,宜精)。

2,減少了重復代碼。

3,使得代碼更加規范化,合理化。

二 繼承的分類。

就向上面的例子:

Aminal 叫做父類,基類,超類。
Person Cat Dog: 子類,派生類。
繼承:可以分單繼承,多繼承

這里需要補充一下python中類的種類(繼承需要):

在python2x版本中存在兩種類.:
  ?個叫經典類. 在python2.2之前. ?直使?的是經典類. 經典類在基類的根如果什么都不寫.
  ?個叫新式類. 在python2.2之后出現了新式類. 新式類的特點是基類的根是object類。
python3x版本中只有一種類:
python3中使?的都是新式類. 如果基類誰都不繼承. 那這個類會默認繼承 object

三,單繼承。

3.1 類名,對象執行父類方法

class Aniaml(object):type_name = '動物類'def __init__(self,name,sex,age):self.name = nameself.age = ageself.sex = sexdef eat(self):print(self)print('吃東西')class Person(Aniaml):passclass Cat(Aniaml):passclass Dog(Aniaml):pass# 類名: print(Person.type_name) # 可以調用父類的屬性,方法。 Person.eat(111) print(Person.type_name)# 對象: # 實例化對象 p1 = Person('春哥','',18) print(p1.__dict__) # 對象執行類的父類的屬性,方法。 print(p1.type_name) p1.type_name = '666' print(p1) p1.eat()類名,對象分別調用父類方法

?

3.2 執行順序

class Aniaml(object):type_name = '動物類'def __init__(self,name,sex,age):self.name = nameself.age = ageself.sex = sexdef eat(self):print(self)print('吃東西')class Person(Aniaml):def eat(self):print('%s 吃飯'%self.name)class Cat(Aniaml):passclass Dog(Aniaml):passp1 = Person('barry','',18) # 實例化對象時必須執行__init__方法,類中沒有,從父類找,父類沒有,從object類中找。 p1.eat() # 先要執行自己類中的eat方法,自己類沒有才能執行父類中的方法。執行順序

?

3.3同時執行類以及父類方法

class Aniaml(object):type_name = '動物類'def __init__(self,name,sex,age):self.name = nameself.age = ageself.sex = sexdef eat(self):print('吃東西')class Person(Aniaml):def __init__(self,name,sex,age,mind):''' self = p1name = '春哥'sex = 'laddboy'age = 18mind = '有思想'''' # Aniaml.__init__(self,name,sex,age) # 方法一self.mind = minddef eat(self):super().eat()print('%s 吃飯'%self.name) class Cat(Aniaml):passclass Dog(Aniaml):pass# 方法一: Aniaml.__init__(self,name,sex,age) # p1 = Person('春哥','laddboy',18,'有思想') # print(p1.__dict__)# 對于方法一如果不理解: # def func(self): # print(self) # self = 3 # func(self)

?

方法一:

如果想執行父類的func方法,這個方法并且子類中夜用,那么就在子類的方法中寫上:

父類.func(對象,其他參數)

舉例說明:

class Aniaml(object):type_name = '動物類'def __init__(self,name,sex,age):self.name = nameself.age = ageself.sex = sexdef eat(self):print('吃東西')class Person(Aniaml):def __init__(self,name,sex,age,mind):'''self = p1name = '春哥'sex = 'laddboy'age = 18mind = '有思想''''# Aniaml.__init__(self,name,sex,age) # 方法一self.mind = minddef eat(self):super().eat()print('%s 吃飯'%self.name) class Cat(Aniaml):passclass Dog(Aniaml):pass# 方法一: Aniaml.__init__(self,name,sex,age) # p1 = Person('春哥','laddboy',18,'有思想') # print(p1.__dict__)# 對于方法一如果不理解: # def func(self): # print(self) # self = 3 # func(self)

方法二:

利用super,super().func(參數)

class Aniaml(object):type_name = '動物類'def __init__(self,name,sex,age):self.name = nameself.age = ageself.sex = sexdef eat(self):print('吃東西')class Person(Aniaml):def __init__(self,name,sex,age,mind):'''self = p1name = '春哥'sex = 'laddboy'age = 18mind = '有思想''''# super(Person,self).__init__(name,sex,age) # 方法二super().__init__(name,sex,age) # 方法二self.mind = minddef eat(self):super().eat()print('%s 吃飯'%self.name) class Cat(Aniaml):passclass Dog(Aniaml):pass # p1 = Person('春哥','laddboy',18,'有思想') # print(p1.__dict__)

單繼承練習題:

# 1
class Base:
def __init__(self, num):
self.num = num
def func1(self):
print(self.num)

class Foo(Base):
pass
obj = Foo(123)
obj.func1() # 123 運?的是Base中的func1

# 2
class Base:
def __init__(self, num):
self.num = num
def func1(self):
print(self.num)
class Foo(Base):
def func1(self):
print("Foo. func1", self.num)
obj = Foo(123)
obj.func1() # Foo. func1 123 運?的是Foo中的func1

# 3
class Base:
def __init__(self, num):
self.num = num
def func1(self):
print(self.num)
class Foo(Base):
def func1(self):
print("Foo. func1", self.num)
obj = Foo(123)
obj.func1() # Foo. func1 123 運?的是Foo中的func1
# 4
class Base:
def __init__(self, num):
self.num = num
def func1(self):
print(self.num)
self.func2()
def func2(self):
print("Base.func2")
class Foo(Base):
def func2(self):
print("Foo.func2")
obj = Foo(123)
obj.func1() # 123 Foo.func2 func1是Base中的 func2是?類中的
# 再來
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

# 再來
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.func1() # 那筆來吧. 好好算

# 1 class Base:def __init__(self, num):self.num = numdef func1(self):print(self.num)class Foo(Base):pass obj = Foo(123) obj.func1() # 123 運?的是Base中的func1 # 2 class Base:def __init__(self, num):self.num = numdef func1(self):print(self.num) class Foo(Base):def func1(self):print("Foo. func1", self.num) obj = Foo(123) obj.func1() # Foo. func1 123 運?的是Foo中的func1 # 3 class Base:def __init__(self, num):self.num = numdef func1(self):print(self.num) class Foo(Base):def func1(self):print("Foo. func1", self.num) obj = Foo(123) obj.func1() # Foo. func1 123 運?的是Foo中的func1 # 4 class Base:def __init__(self, num):self.num = numdef func1(self):print(self.num)self.func2()def func2(self):print("Base.func2") class Foo(Base):def func2(self):print("Foo.func2") obj = Foo(123) obj.func1() # 123 Foo.func2 func1是Base中的 func2是?類中的 # 再來 class Base:def __init__(self, num):self.num = numdef 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# 再來 class Base:def __init__(self, num):self.num = numdef 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.func1() # 那筆來吧. 好好算

?

四,多繼承

class ShenXian: # 神仙def fei(self):print("神仙都會?") class Monkey: # 猴def chitao(self):print("猴?喜歡吃桃?") class SunWukong(ShenXian, Monkey): # 孫悟空是神仙, 同時也是?只猴pass sxz = SunWukong() # 孫悟空 sxz.chitao() # 會吃桃? sxz.fei() # 會?

  此時, 孫悟空是?只猴?, 同時也是?個神仙. 那孫悟空繼承了這兩個類. 孫悟空?然就可以執?這兩個類中的?法.?多繼承?起來簡單. 也很好理解. 但是多繼承中, 存在著這樣?個問題. 當兩個?類中出現了重名?法的時候. 這時該怎么辦呢? 這時就涉及到如何查找?類?法的這么?個問題.即MRO(method resolution order) 問題. 在python中這是?個很復雜的問題. 因為在不同的python版本中使?的是不同的算法來完成MRO的.

這里需要補充一下python中類的種類(繼承需要):

在python2x版本中存在兩種類.:
  ?個叫經典類. 在python2.2之前. ?直使?的是經典類. 經典類在基類的根如果什么都不寫.
  ?個叫新式類. 在python2.2之后出現了新式類. 新式類的特點是基類的根是object類。
python3x版本中只有一種類:
python3中使?的都是新式類. 如果基類誰都不繼承. 那這個類會默認繼承 object

4.1經典類的多繼承

雖然在python3中已經不存在經典類了. 但是經典類的MRO最好還是學?學. 這是?種樹形結構遍歷的?個最直接的案例. 在python的繼承體系中. 我們可以把類與類繼承關系化成?個樹形結構的圖. 來, 上代碼:

?代碼示例

對付這種mro畫圖就可以:

繼承關系圖已經有了. 那如何進?查找呢? 記住?個原則. 在經典類中采?的是深度優先,遍歷?案. 什么是深度優先. 就是?條路走到頭. 然后再回來. 繼續找下?個.

圖中每個圈都是準備要送雞蛋的住址. 箭頭和?線表?線路. 那送雞蛋的順序告訴你入?在最下?R. 并且必須從左往右送. 那怎么送呢?

如圖. 肯定是按照123456這樣的順序來送. 那這樣的順序就叫深度優先遍歷. ?如果是142356呢? 這種被稱為?度優先遍歷. 好了. 深度優先就說這么多. 那么上?那個圖怎么找的呢? MRO是什么呢? 很簡單. 記住. 從頭開始. 從左往右. ?條路跑到頭, 然后回頭. 繼續?條路跑到頭. 就是經典類的MRO算法.?

類的MRO: Foo-> H -> G -> F -> E -> D -> B -> A -> C. 你猜對了么?

4.2新式類的多繼承

4.2.1 mro序列

MRO是一個有序列表L,在類被創建時就計算出來。
通用計算公式為:

mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )
(其中Child繼承自Base1, Base2)

如果繼承至一個基類:class B(A)?
這時B的mro序列為

mro( B ) = mro( B(A) ) = [B] + merge( mro(A) + [A] ) = [B] + merge( [A] + [A] ) = [B,A]

?

如果繼承至多個基類:class B(A1, A2, A3 …)?
這時B的mro序列

mro(B) = mro( B(A1, A2, A3 …) ) = [B] + merge( mro(A1), mro(A2), mro(A3) ..., [A1, A2, A3] ) = ...

計算結果為列表,列表中至少有一個元素即類自己,如上述示例[A1,A2,A3]。merge操作是C3算法的核心。

4.2.2. 表頭和表尾
表頭:?
  列表的第一個元素

表尾:?
  列表中表頭以外的元素集合(可以為空)

示例?
  列表:[A, B, C]?
  表頭是A,表尾是B和C

4.2.3. 列表之間的+操作
+操作:

[A] + [B] = [A, B]
(以下的計算中默認省略)
---------------------

merge操作示例:

如計算merge( [E,O], [C,E,F,O], [C] ) 有三個列表 : ① ② ③1 merge不為空,取出第一個列表列表①的表頭E,進行判斷 各個列表的表尾分別是[O], [E,F,O],E在這些表尾的集合中,因而跳過當前當前列表 2 取出列表②的表頭C,進行判斷C不在各個列表的集合中,因而將C拿出到merge外,并從所有表頭刪除merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] ) 3 進行下一次新的merge操作 ...... ---------------------

計算mro(A)方式:

mro(A) = mro( A(B,C) )原式= [A] + merge( mro(B),mro(C),[B,C] )mro(B) = mro( B(D,E) )= [B] + merge( mro(D), mro(E), [D,E] ) # 多繼承= [B] + merge( [D,O] , [E,O] , [D,E] ) # 單繼承mro(D(O))=[D,O]= [B,D] + merge( [O] , [E,O] , [E] ) # 拿出并刪除D= [B,D,E] + merge([O] , [O])= [B,D,E,O]mro(C) = mro( C(E,F) )= [C] + merge( mro(E), mro(F), [E,F] )= [C] + merge( [E,O] , [F,O] , [E,F] )= [C,E] + merge( [O] , [F,O] , [F] ) # 跳過O,拿出并刪除= [C,E,F] + merge([O] , [O])= [C,E,F,O]原式= [A] + merge( [B,D,E,O], [C,E,F,O], [B,C])= [A,B] + merge( [D,E,O], [C,E,F,O], [C])= [A,B,D] + merge( [E,O], [C,E,F,O], [C]) # 跳過E= [A,B,D,C] + merge([E,O], [E,F,O])= [A,B,D,C,E] + merge([O], [F,O]) # 跳過O= [A,B,D,C,E,F] + merge([O], [O])= [A,B,D,C,E,F,O] ---------------------

?

結果OK. 那既然python提供了. 為什么我們還要如此?煩的計算MRO呢? 因為筆
試.......你在筆試的時候, 是沒有電腦的. 所以這個算法要知道. 并且簡單的計算要會. 真是項?
開發的時候很少有?這么去寫代碼.?

這個說完了. 那C3到底怎么看更容易呢? 其實很簡單. C3是把我們多個類產?的共同繼
承留到最后去找. 所以. 我們也可以從圖上來看到相關的規律. 這個要?家??多寫多畫圖就
能感覺到了. 但是如果沒有所謂的共同繼承關系. 那?乎就當成是深度遍歷就可以了

轉載于:https://www.cnblogs.com/baili-luoyun/p/10403444.html

總結

以上是生活随笔為你收集整理的day 17python 面对对象之继承的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。