7.27學(xué)習(xí) 面向?qū)ο螅ㄏ拢ɡ^承、多態(tài))

面向?qū)ο缶幊趟枷氲陌l(fā)展歷程

面向?qū)ο?Object Oriented):是一種編程思想绒北,是一種對現(xiàn)實(shí)世界的理解和抽閑的方法黎侈,已經(jīng)從程序設(shè)計(jì)開發(fā),擴(kuò)展到了數(shù)據(jù)庫系統(tǒng)闷游、交互式界面峻汉、應(yīng)用結(jié)構(gòu)、應(yīng)用平臺脐往、分布式系統(tǒng)休吠、網(wǎng)絡(luò)管理、人工智能等等各個(gè)應(yīng)用方向业簿。

面向?qū)ο蟪霈F(xiàn)以前瘤礁,結(jié)構(gòu)化程序設(shè)計(jì)是程序設(shè)計(jì)的主流,結(jié)構(gòu)化程序設(shè)計(jì)又稱為面向過程的程序設(shè)計(jì)梅尤。在面向過程程序設(shè)計(jì)中柜思,問題被看作一系列需要完成的任務(wù)岩调,函數(shù)(在此泛指例程、函數(shù)赡盘、過程)用于完成這些任務(wù)誊辉,解決問題的焦點(diǎn)集中于函數(shù)。其中函數(shù)是面向過程的亡脑,即它關(guān)注如何根據(jù)規(guī)定的條件完成指定的任務(wù)。在多函數(shù)程序中邀跃,許多重要的數(shù)據(jù)被放置在全局?jǐn)?shù)據(jù)區(qū)霉咨,這樣它們可以被所有的函數(shù)訪問。每個(gè)函數(shù)都可以具有它們自己的局部數(shù)據(jù)拍屑。

但這種結(jié)構(gòu)很容易造成全局?jǐn)?shù)據(jù)在無意中被其他函數(shù)改動(dòng)途戒,因而程序的正確性不易保證。面向?qū)ο蟪绦蛟O(shè)計(jì)的出發(fā)點(diǎn)之一就是彌補(bǔ)面向過程程序設(shè)計(jì)中的一些缺點(diǎn):對象是程序的基本元素僵驰,它將數(shù)據(jù)和操作緊密地連結(jié)在一起喷斋,并保護(hù)數(shù)據(jù)不會(huì)被外界的函數(shù)意外地改變。

面向?qū)ο笤O(shè)計(jì)方法以對象為基礎(chǔ)蒜茴,利用特定的軟件工具直接完成從對象客體的描述到軟件結(jié)構(gòu)之間的轉(zhuǎn)換星爪。這是面向?qū)ο笤O(shè)計(jì)方法最主要的特點(diǎn)和成就。面向?qū)ο笤O(shè)計(jì)方法的應(yīng)用解決了傳統(tǒng)結(jié)構(gòu)化開發(fā)方法中客觀世界描述工具與軟件結(jié)構(gòu)的不一致性問題粉私,縮短了開發(fā)周期顽腾,解決了從分析和設(shè)計(jì)到軟件模塊結(jié)構(gòu)之間多次轉(zhuǎn)換映射的繁雜過程,是一種很有發(fā)展前途的系統(tǒng)開發(fā)方法诺核。

最典型的動(dòng)態(tài)語言有JavaScript, Python, Ruby等等抄肖。它們一個(gè)重大的變化就是將類的信息改變?yōu)閯?dòng)態(tài)的,并提出了Ducking Type的概念窖杀。這在很大程度上提升了編程的生產(chǎn)力漓摩。


封裝的意義和操作過程

封裝?將對象敏感的數(shù)據(jù)封裝在類的內(nèi)部入客,不讓外界直接訪問管毙,而是通過當(dāng)前類提供的set/get方法間接訪問數(shù)據(jù),此時(shí)就可以在set/get中添加限制條件進(jìn)行訪問數(shù)據(jù)的控制痊项。

封裝實(shí)現(xiàn)的步驟:

定義類型锅风,封裝零散數(shù)據(jù)【抽象的屬性】

[使用__slots__屬性,限制當(dāng)前類的屬性列表->為了代碼的統(tǒng)一性]

所有屬性私有化【屬性使用雙下劃綫開頭鞍泉,外界就不能直接訪問這樣的屬性了】

給每個(gè)屬性提供set/get方法皱埠,在方法中添加限制條件

高級封裝

使用@property和@get_method.setter注解,來注釋set/get方法咖驮,隱藏set/get方法的實(shí)現(xiàn)边器,讓方法的使用方式和屬性一致

偽方法重載:python中训枢,默認(rèn)不提供方法重載,但是在高級封裝的過程中忘巧,又出現(xiàn)了類似方法重載的代碼語法恒界,所以~稱之為偽方法重載。

對方法的封裝

在封裝的過程中砚嘴,除了封裝私有屬性十酣,還可以針對一些底層的操作方法進(jìn)行私有化,將方法封裝在類的內(nèi)部际长,通過提供的一個(gè)公共方法來控制該方法的訪問權(quán)限

再說各種變量

  • 全局變量:程序中任何位置都可以訪問的數(shù)據(jù)耸采;聲明在類的外部

  • 類變量/類屬性:當(dāng)前類創(chuàng)建的各種對象,可以共享的數(shù)據(jù)工育;聲明在類的內(nèi)部虾宇,方法的外部

  • 成員變量/成員屬性:【創(chuàng)建的指定對象的特征】被對象所私有,對象之間不能使用對方的數(shù)據(jù)

  • 局部變量:聲明在對象的方法或者函數(shù)中如绸,函數(shù)中有效嘱朽,出了函數(shù)無效【變量銷毀】


繼承的意義和操作過程

一個(gè)類型繼承另一個(gè)類型,當(dāng)前類型就會(huì)擁有另一個(gè)類型的公共的屬性和方法怔接,達(dá)到代碼的重復(fù)使用的目的搪泳。

繼承是讓我們抽象的對象之間存在一定的所屬關(guān)系

在繼承關(guān)系中,我們一定要明確會(huì)出現(xiàn)這樣的一種關(guān)系~父類扼脐、子類森书,子類繼承自父類柒竞,可以繼承父類中的公開的屬性和方法(不能繼承私有的屬性或者方法)

python中所有的對象都是直接或者間接繼承自object對象的:

class Person(object):

    pass

繼承的語法:

    class 類型(被繼承的類型):

        pass

繼承中出現(xiàn)的術(shù)語:

繼承是類型之間的關(guān)系
繼承中锌钮,首先必須是兩個(gè)或者兩個(gè)以上的類型之間的關(guān)系坛缕,注意是類型之間的關(guān)系

  1. 父類:被繼承的類幸冻,也稱為基類陡鹃、超類

  2. 子類:當(dāng)前類常潮,也稱為派生類

  3. 子類繼承父類保礼,體現(xiàn)的時(shí)A is a B的關(guān)系

  4. 子類繼承父類镐依,就可以使用父類中所有的公開的屬性和方法

繼承鏈

A繼承B须喂,B繼承C吁断,C繼承D

A直接繼承了B,間接繼承了C,D坞生;此時(shí)A創(chuàng)建的對象仔役,可以同時(shí)使用B,C,D中所有公開的屬性和方法

多繼承

python中,一個(gè)類型是己,可以同時(shí)繼承多個(gè)類型又兵,同時(shí)擁有所有繼承類型的所有公開的屬性和方法
備注:在進(jìn)行代碼設(shè)計(jì)的過程中,可能會(huì)出現(xiàn)多繼承,所以盡量不要在父類中定義相同名稱的屬性或者方法
備注2:如果父類中出現(xiàn)了相同名稱的屬性和方法沛厨,在使用的時(shí)候子類調(diào)用時(shí)會(huì)優(yōu)先繼承優(yōu)先調(diào)用宙地。
在python的繼承機(jī)制中,私有的屬性是不允許被繼承和互相訪問的逆皮,子類不能繼承和訪問父類中私有的屬性和方法宅粥,父類同樣也不能訪問子類中私有的屬性和方法
子類只能繼承父類中公開的屬性和方法

子類中可以通過父類的名稱或者super()來訪問父類的屬性和方法

# 父類

class Person(object):

  def __init__(self, name, age):

      self.__name = name

      self.__age = age

  def play(self):

      print(self.__name + "在玩游戲")

# 子類

class Man(Person):

  def __init__(self, name, age):

      # 通過父類名稱訪問父類中初始化的方法

      Person.__init__(self, name,age)

# 子類

class Women(Person):

  def __init__(self, name, age):

      # 通過super()訪問父類初始化的方法

      # super(Women, self).__init....super中的參數(shù)可以省略

      super().__init__(self, name, age)

方法重寫:

子類在自己類中重新定義父類中已經(jīng)存在的方法,在執(zhí)行該方法時(shí)电谣,如果子類中沒有重寫就直接調(diào)用父類的方法秽梅,如果子類重寫了該方法,就直接調(diào)用子類重寫的方法剿牺!

# 父類

class Person(object):

    def play(self):

        print("Person中玩游戲的方法執(zhí)行了...")

# 子類

class Children(Person):

     # 重寫父類中play方法

     def play(self):

        print("Children中玩游戲的方法執(zhí)行.....")

# 創(chuàng)建子類對象

c = Children()

c.play()

# 執(zhí)行結(jié)果

~Children中玩游戲的方法執(zhí)行.....

多態(tài)的意義和操作過程

程序在運(yùn)行的過程中风纠,根據(jù)傳遞的參數(shù)的不同,執(zhí)行不同的函數(shù)或者操作不同的代碼牢贸,這種在運(yùn)行過程中才確定調(diào)用的方式成為運(yùn)行時(shí)多態(tài)

方法重寫實(shí)現(xiàn)的運(yùn)行時(shí)多態(tài),對象在執(zhí)行具體的方法時(shí)镐捧,會(huì)直接執(zhí)行父類中繼承的對應(yīng)的方法潜索,如果該方法在子類中重寫了,就會(huì)執(zhí)行子類中重寫過的方法懂酱,實(shí)現(xiàn)的是一種運(yùn)行過程中的多態(tài)處理

多態(tài)執(zhí)行過程

多態(tài)實(shí)現(xiàn)代碼如下:

class Person:
    def __init__(self, name, age, health):
        self.name = name
        self.age = age
        self.health = health
    # 治愈康復(fù)
    def recure(self):
        print("[%s]康復(fù)了,當(dāng)前健康值%s\n" % (self.name, self.health))

# 子類
class Man(Person):
    def __init__(self, name, age, health):
        Person.__init__(self, name, age, health)
    def recure(self):
        print("[%s]男的我終于康復(fù)了,當(dāng)前健康值%s\n" % (self.name, self.health))

class Woman(Person):
    def __init__(self, name, age, health):
        Person.__init__(self, name, age, health)
    def recure(self):
        print("[%s]女的我終于康復(fù)了,當(dāng)前健康值%s\n" % (self.name, self.health))

class Animal:
    # name姓名 age年齡 health健康值【0~50極度虛弱,51~70亞健康,71~85健康竹习,86~100強(qiáng)壯】
    def __init__(self, name, age, health):
        self.name = name
        self.age = age
        self.health = health
    # 康復(fù)的方法
    def recure(self):
        print("[%s]嘿嘿嘿,終于康復(fù)了列牺,當(dāng)前健康值%s\n" % (self.name, self.health))

# 醫(yī)院
class Hospital:
    def __init__(self):
        self.__name = "人民醫(yī)院"
    # 醫(yī)院治療患者整陌,因此對象是一個(gè)人person
    # 若不是人,則不治療并報(bào)出錯(cuò)誤
    def care(self, person):
        if isinstance(person, Person):
            if (person.health > 0) and (person.health <= 50):
                print("手術(shù)....")
                person.health += 30
                person.recure()
            elif (person.health > 50) and (person.health < 75):
                print("吃藥....")
                person.health += 15
                person.recure()
            else:
                print("沒有生病")
        else:
            print("不是人")


hospital = Hospital()
Pi = Person("Pi", 27, 40)
Mr_wang = Man("王老菊", 29, 51)
Mian = Woman("免免", 28, 49)
pig = Animal("小豬", 10, 88)

hospital.care(Mr_wang)
hospital.care(Pi)
hospital.care(Mian)
hospital.care(pig)

運(yùn)行結(jié)果

同時(shí)如果功能需要擴(kuò)展瞎领,需要多出來一個(gè)人物類型:小孩泌辫,小孩也會(huì)生病,也需要治療~此時(shí)對于功能的擴(kuò)展非常簡潔九默,值需要添加如下代碼就可以搞定:

# 創(chuàng)建一個(gè)小孩類型震放,繼承自Person

class Children(Person):

    def __init__(self, name):

        Person.__init__(self, name)

# 創(chuàng)建具體的小孩對象

c = Children("小家伙")

h.care(c) # 執(zhí)行結(jié)果~小家伙康復(fù)了

可以看到這里擴(kuò)展一個(gè)功能變得非常的簡單,對象和對象之間的協(xié)同關(guān)系由于繼承多態(tài)的存在讓功能的擴(kuò)展實(shí)現(xiàn)起來比較快捷了驼修。

通過isinstance()函數(shù)進(jìn)行變量所屬數(shù)據(jù)類型的判斷

這樣只有Person類型才可以通過進(jìn)行care()

__slots__ 殿遂,該屬性的值是一個(gè)元組,元組中定義了類中可以出現(xiàn)的所有成員屬性的名稱

元組中規(guī)范了可能出現(xiàn)在類的成員屬性列表乙各。

類在創(chuàng)建好對象之后墨礁,可以在對象上直接掛在屬性,這在一定程度上對于程序處理的靈活度有所提升耳峦,但是同樣的恩静,過于靈活的代碼都會(huì)極大的降低代碼的可讀性,所以python提供了slots這樣的類屬性進(jìn)行規(guī)范蹲坷,規(guī)范類屬性中只能出現(xiàn)的成員屬性的列表蜕企,防止惡意的擴(kuò)展咬荷。

__str__()可以更改我們的類的對象的打印輸出結(jié)果

這個(gè)__str__()方法是從object對象繼承而來的,我們這里只是對它進(jìn)行了方法重寫轻掩。

另外幸乒,在命令行操作過程中,如果不用print()方法打印而是直接輸入對象唇牧,會(huì)發(fā)現(xiàn)執(zhí)行的結(jié)果又是讓人晦澀難懂的東西了罕扎,在命令行直接使用對象調(diào)用的不是對象的__str__()方法,而是__repr__()方法丐重,只需要簡單的修改即可

__call__()方法腔召,主要用于對象快捷執(zhí)行而存在的一個(gè)魔術(shù)方法,方便進(jìn)行對象中某些重要數(shù)據(jù)的初始化整理工作等扮惦。

多繼承時(shí)臀蛛,

當(dāng)前類繼承了一個(gè)或者多個(gè)父類,當(dāng)前類就同時(shí)繼承了父類中的公開的屬性和函數(shù)崖蜜,如果不同的父類中出現(xiàn)相同的屬性/函數(shù)浊仆,就需要明確執(zhí)行的過程

# 定義了一個(gè)基礎(chǔ)類

class Person(object):

    def __init__(self):

        self.name = "tom"

class Student(Person):

    def eat(self):

        print("吃食堂....")

    def respect(self):

        print("尊師重道")

class Son(Person):

    def eat(self):

        print("吃美食...")

    def fealty(self):

        print("尊老愛幼")

# User類型,繼承了兒子類型豫领、學(xué)生類型

# 同時(shí)擁有兒子類型和學(xué)生類型中所有的公共屬性和方法

class User(Son, Student):

    pass

# 創(chuàng)建對象

u = User()

# u是學(xué)生角色

u.respect()

# u是兒子角色

u.fealty()

# 吃飯

# 如果繼承的多個(gè)父類中抡柿,出現(xiàn)了相同的屬性和方法,就會(huì)執(zhí)行方法或者屬性的搜索

# 過程等恐,搜索到對應(yīng)的屬性和方法洲劣,立即執(zhí)行,中斷搜索

# 屬性和方法的搜索過程课蔬,可以通過  類型.__mro__ 魔法屬性進(jìn)行查看

# 優(yōu)先繼承囱稽,優(yōu)先執(zhí)行

u.eat()

print(User.__mro__)# method from object

#運(yùn)行結(jié)果

~

尊師重道

尊老愛幼

吃美食...

(<class '__main__.User'>, <class '__main__.Son'>, <class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>)

一旦出現(xiàn)多重繼承,就會(huì)出現(xiàn)這樣繼承的多個(gè)父類中出現(xiàn)了多個(gè)相同名稱的變量或者方法的情況二跋,使用的這些變量和方法的時(shí)候一定要注意一個(gè)原則粗悯,先繼承誰就使用誰的變量或者方法!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末同欠,一起剝皮案震驚了整個(gè)濱河市样傍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铺遂,老刑警劉巖衫哥,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異襟锐,居然都是意外死亡撤逢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚊荣,“玉大人初狰,你說我怎么就攤上這事』ダ” “怎么了奢入?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長媳叨。 經(jīng)常有香客問我腥光,道長,這世上最難降的妖魔是什么糊秆? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任武福,我火速辦了婚禮,結(jié)果婚禮上痘番,老公的妹妹穿的比我還像新娘捉片。我一直安慰自己,他們只是感情好汞舱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布伍纫。 她就那樣靜靜地躺著,像睡著了一般兵拢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上逾礁,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天说铃,我揣著相機(jī)與錄音,去河邊找鬼嘹履。 笑死腻扇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的砾嫉。 我是一名探鬼主播幼苛,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼焕刮!你這毒婦竟也來了舶沿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤配并,失蹤者是張志新(化名)和其女友劉穎括荡,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體溉旋,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡畸冲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邑闲。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡算行,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出苫耸,到底是詐尸還是另有隱情州邢,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布鲸阔,位于F島的核電站偷霉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏褐筛。R本人自食惡果不足惜类少,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望渔扎。 院中可真熱鬧硫狞,春花似錦、人聲如沸晃痴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倘核。三九已至泣侮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間紧唱,已是汗流浹背活尊。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漏益,地道東北人蛹锰。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像绰疤,于是被迫代替她去往敵國和親铜犬。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容