日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

第二十三章:面向对象(3)

發(fā)布時(shí)間:2023/12/20 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第二十三章:面向对象(3) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.繼承的另一種使用方式?? *****

最常見的是直接繼承一個(gè)已經(jīng)存在的類

當(dāng)你想要?jiǎng)?chuàng)建一個(gè)新的類 發(fā)現(xiàn)這個(gè)類中的一些 在某一個(gè)類中已經(jīng)存在

那就沒有必要從頭開始寫 ,可以直接繼承已有的類 然后做補(bǔ)充

?

注意注意::::::

?

?

class MyList(list):
? ?def __init__(self,element_cls):
? ? ? ?# 當(dāng)你覆蓋了init方法時(shí)
? ? ? ?# 不要忘記調(diào)用super().init函數(shù)讓父類完成原有的初始化操作
? ? ? ?super().__init__()
? ? ? ?self.element_cls = element_cls
?
? ? ? ?
? ?def append(self, object):
? ? ? ?# if isinstance(object,str)
? ? ? ?if object.__class__ == self.element_cls:
? ? ? ? ? ?super().append(object)
? ? ? ?else:
? ? ? ? ? ?print("只能存儲%s類型!" % self.element_cls.__name__)
? ? ? ? ? ?

?

2.super()的問題? mro列表?

python支持多繼承? 一個(gè)類可以同時(shí)繼承多個(gè)父類

好處是更加靈活

問題是:屬性的查找順序該怎么確定

# 問題:多繼承時(shí)如果多個(gè)父類中出現(xiàn)了同名的屬性/函數(shù)
# 你不能用眼睛去判斷查找順序 ,需要使用mro列表來查看真正的繼承順序
# 總結(jié):super在訪問父類屬性時(shí) 是按照mro列表一層層往上找的
?
#測試
class A:
? ?def test(self):
? ? ? ?print("from A")
? ? ? ?super().test() # 應(yīng)該報(bào)錯(cuò)..... 但是卻執(zhí)行成功了
class B:
? ?def test(self):
? ? ? ?print("from B")
? ?pass
?
class C(A,B):
? ?pass
?
c = C()
c.test()
?
#最后:盡量不要使用多繼承

組合:

"""
組合:
指的是 一個(gè)類把另一個(gè)類的對象作為自己的屬性 就稱之為組合
無處不在
當(dāng)你定義一個(gè)類 并且這個(gè)類擁有某種類型的屬性時(shí) 就稱之為組合
?
都是用用來重用代碼的方式:
組合描述的是 什么擁有什么的關(guān)系 ? 學(xué)生 有 書 學(xué)生有手機(jī)
基礎(chǔ)描述的是 什么是什么的關(guān)系 ? ? 麥兜是豬 ? 豬豬俠也是豬
"""
?
?
# class Person:
# ? ? def __init__(self,name):
# ? ? ? ? self.name = name
#
#
# p = Person("rose")
# print(p.name)
?
?
class PC:
? ?def open_app(self,app_name):
? ? ? ?print("open %s" % app_name)
?
class OldBoyStudent:
? ?def __init__(self,PC,notebook):
? ? ? ?self.PC = PC
? ? ? ?self.notebook = notebook
? ?pass
?
pc = PC()
notebook = PC()
?
?
stu = OldBoyStudent(pc,notebook)

3.菱形繼承問題? ***

?

新式類與經(jīng)典類

# 在py2中 A就是一個(gè)經(jīng)典類
# class A:
# ? ? pass
?
# 如果你的代碼需要兼容py2 那應(yīng)該顯式的繼承object 無論是直接還是間接繼承
class B(object):
? ?pass
?
class A(B):
? ?pass

?

?

?

多層菱形繼承

?

class A:
? ?# a = 1
? ?pass
?
class B(A):
? ?# a = 2
? ?pass
?
class C(A):
? ?# a = 3
? ?pass
?
class D(A):
? ?# a = 4
? ?pass
?
class E(B,C,D):
? ?# a = 5
? ?pass
?
e1 = E()
# print(e1.a)
# 新式類的順序
# E B C D A object
# 經(jīng)典類的順序
# E B A C D
# print(E.mro())
?
注意:經(jīng)典類沒有mro列表

?

4.接口 ***

接口是什么

例如USB??

電腦內(nèi)部具備USB相應(yīng)的功能 如果要使用的話?? 就必須給外界提供一個(gè)使用方式,該方式就稱之為接口 ,

在程序中功能通常是用函數(shù)來表示, 對于外界而言 無需清楚函數(shù)時(shí)如何實(shí)現(xiàn)的 只要知道函數(shù)名即可, 這個(gè)函數(shù)名稱就可以稱之為接口?

外界調(diào)用接口就能完成某個(gè)任務(wù)

接口其實(shí)就是一組功能的定義,但是只清楚函數(shù)名稱,而沒有具體的實(shí)現(xiàn)細(xì)節(jié)

相當(dāng)于是一套規(guī)范,

例如USB?? 規(guī)定了接口的外觀,大小,以及每條線路的功能是什么

硬件開發(fā)商照著這個(gè)USB協(xié)議來生產(chǎn)設(shè)備,就可以被電腦使用

class USB:
?
? ?def open(self):
? ? ? ?pass
?
? ?def close(self):
? ? ? ?pass
?
? ?def work(self):
? ? ? ?pass

好處:

使用接口可以提高程序的擴(kuò)展性

只要對象按照接口規(guī)定方法來實(shí)現(xiàn),使用者就可以無差別使用所有對象

接口與抽象類

抽象:

指的是 不清楚 不具體 看不懂

抽象方法:

指的是 沒有函數(shù)體的方法?? 用@abc.abstractmethod 裝飾器

如果類中具備抽象方法 那么這個(gè)類就稱之為抽象類

抽象類的特點(diǎn):

不能直接實(shí)例化? 必須有子類覆蓋了所有抽象方法后才能實(shí)例化子類

與接口的區(qū)別:

接口是指只有方法聲明而沒有實(shí)現(xiàn)體 ,? 接口中所有方法都是抽象的

import abc
?
class Test(metaclass=abc.ABCMeta):
?
? ?@abc.abstractmethod
? ?def say_hi(self):
? ? ? ?pass
?
class TT(Test):
?
? ?def say_hi(self):
? ? ? ?print("i am TT obj")
?
t = TT()
t.say_hi()

?

問題:如果接口的子類沒有實(shí)現(xiàn)接口中的方法,那是沒有任何意義的

抽象類之所以出現(xiàn)的意義:通過抽象類來強(qiáng)行限制子類必須覆蓋所有的抽象方法

?

鴨子類型

說如果一個(gè)對象叫聲像鴨子,走路像鴨子,長得像鴨子,那它就是鴨子

是python 推薦的方式,python不喜歡強(qiáng)行限制你

?
class PC():
?
? ?def conntent_device(self, usb_device):
? ? ? ?usb_device.open()
? ? ? ?usb_device.work()
? ? ? ?usb_device.close()
?
class Mouse:
? ?# 實(shí)現(xiàn)接口規(guī)定的所有功能
? ?def open(self):
? ? ? ?print("mouse opened")
?
? ?def work(self):
? ? ? ?print("mouse working...")
?
? ?def close(self):
? ? ? ?print("mouse closed")
?
mouse = Mouse()
pc = PC()
?
pc.conntent_device(mouse)
?
?
?
class KeyBoard:
? ?def open(self):
? ? ? ?print("KeyBoard opened")
?
? ?def work(self):
? ? ? ?print("KeyBoard working...")
?
? ?def close(self):
? ? ? ?print("KeyBoard closed")
?
key1 = KeyBoard()
?
# 如果key1的特征和行為都像USB設(shè)備 那就把它當(dāng)做USB設(shè)備來使用
# 對于使用者而言可以不用關(guān)心這個(gè)對象是什么類,是如如何是實(shí)現(xiàn),
pc.conntent_device(key1)
?

?

案例2:

class Linux:
? ?def read_data(self,device):
? ? ? ?data = device.read()
? ? ? ?return data
?
? ?def write_data(self,device,data):
? ? ? ?device.write(data)
?
class Disk:
? ?def read(self):
? ? ? ?print("disk reading....")
? ? ? ?return "這是一個(gè)磁盤上的數(shù)據(jù)"
?
? ?def write(self,data):
? ? ? ?print("disk writing %s..." % data)
?
class UP:
? ?def read(self):
? ? ? ?print("disk reading....")
? ? ? ?return "這是一個(gè)U盤上的數(shù)據(jù)"
?
? ?def write(self,data):
? ? ? ?print("disk writing %s..." % data)
?
?
l = Linux()
?
d = Disk()
data = l.read_data(d)
l.write_data(d,"這是一個(gè)數(shù)據(jù)....")
?
?
up1 = UP()
l.read_data(up1)
l.write_data(up1,"一個(gè)數(shù)據(jù)...")

例如linux 有一句話叫一切皆文件

之所以這么設(shè)計(jì)是為了提高擴(kuò)展性,讓Linux可以無差別對待任何設(shè)備!

?

?

?

今日的知識點(diǎn):

1.繼承的另一種使用方法

繼承一個(gè)已經(jīng)存在的類 并擴(kuò)展新方法? 或修改原來的方法

2.super() 是按照mro列表來查找屬性的

3.組合? 一個(gè)類把另一個(gè)類的對象作為屬性

  • 菱形繼承的問題

    ?

    經(jīng)典類:不是object的子類?? 僅在py2中出現(xiàn)

    深度優(yōu)先

    新式類:object的子類 py3中都是新式類

    先深度 直到有一個(gè)公共父類時(shí),查找其他路線(基于C3算法)

  • 5.接口是一套協(xié)議規(guī)范,具體表現(xiàn):一堆只有方法聲明而沒有實(shí)現(xiàn)體的方法?

    6.抽象類:具備抽象方法的類? 抽象方法時(shí)沒有實(shí)現(xiàn)體的方法?? 不能直接實(shí)例化? 通過abc模塊來實(shí)現(xiàn)

    抽象類既可以以后抽象方法也可以有普通方法

    而接口中全都是抽象方法?

    接口的出現(xiàn)是為了提高擴(kuò)展性,抽象類是為類限制子類必須按照接口要求的來實(shí)現(xiàn)

    鴨子類型

    對于一個(gè)優(yōu)秀的程序員,即時(shí)沒有接口和抽象類的限制,也能寫出一個(gè)具備擴(kuò)展性的程序

    就如何做到:鴨子類型?

    鴨子類型:這個(gè)對象 長的想鴨子 叫聲像鴨子 走路像鴨子? 那它就是鴨子

    就可以把它當(dāng)成鴨子來使用

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/haojunliancheng/p/10882002.html

    總結(jié)

    以上是生活随笔為你收集整理的第二十三章:面向对象(3)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。