# -- coding: utf-8 --# @Time : 2022/8/29 16:31# @Author : siyu.yang# @File : demo_05.py# @desc : 第五章# 面向?qū)ο罄^續(xù)概念# 創(chuàng)建類和對象# 屬性 、 方法# 三大特性之封裝實(shí)現(xiàn)# 三大特性之繼承實(shí)現(xiàn)# 抽象類# 三大特性之多態(tài)實(shí)現(xiàn)# 面向?qū)ο蠡A(chǔ)概念# python 是解釋性語言,但是它同時(shí)和java等高級語言一樣,可以采用面向?qū)ο蟮木幊? 思想和方式進(jìn)行編程。# 什么是面向?qū)ο?Object Oriented)?# 面向?qū)ο笫且环N程序設(shè)計(jì)設(shè)計(jì)方阿飛,它以對象作為基本的單元來構(gòu)建系統(tǒng),它利用對象# 將系統(tǒng)的復(fù)雜性隱形在對象里,從而構(gòu)建出系統(tǒng)。面向?qū)ο蟀ㄈ齻€(gè)過程:面向?qū)ο蠓治?OOA)# 、面向?qū)ο笤O(shè)計(jì)(OOD)、面向?qū)ο缶幊?OOP).# * 面向?qū)ο蠓治鲋傅氖欠治鲆_發(fā)的系統(tǒng)的各個(gè)方面,從而找出類和對象# * 面向?qū)ο笤O(shè)計(jì)指我們設(shè)計(jì)出一些特殊的類(如:抽象類)來表達(dá)系統(tǒng)種不通對象的共性和機(jī)制,# 系統(tǒng)的對象相互協(xié)作,滿足系統(tǒng)需要實(shí)現(xiàn)功能的設(shè)計(jì)過程;# * 面向?qū)ο缶幊讨肝覀兡苡锰囟ǖ拿嫘蛯ο缶幊陶Z言實(shí)現(xiàn)我們的設(shè)計(jì),實(shí)現(xiàn)系統(tǒng)種的對象和類# 的過程。# 即:# 面向?qū)ο? 類:具有相同特征和行為的某一類事物的總稱,是抽象化出來的。# 對象:類中具體的實(shí)例'''# 狗-----顏色、身高、體重(屬性) 抓老鼠、看家(方法)class Dog: # class 類名 color = '黃色' # 類屬性 height = '60cm' weight = 30 # 類中的方法都會(huì)自帶self參數(shù),標(biāo)識當(dāng)前類的所有的屬性和方法 def catch_the_mouse(self): print('我會(huì)抓老鼠') def eat(self): print('我需要吃飯')# 創(chuàng)建對象 對象名 = 類名()tom = Dog()tom.color = '黃色'tom.height = '30cm'jeck = Dog()print('顏色:{},身高:{},體重:{}'.format(tom.color,tom.height,tom.weight))tom.catch_the_mouse()print('顏色:{},身高:{},體重:{}'.format(jeck.color,jeck.height,jeck.weight))jeck.eat()'''# 世界是由深組成的? ---- 萬物皆可是對象# 對象的特性 ---- 屬性# 屬性 ---- 對象具有的各種特性# 每個(gè)對象的每個(gè)屬性都擁有特定值# 對象的特征 ---- 方法# 方法 ---- 對象執(zhí)行的操作# 類是對象的類型# 不同于一般數(shù)據(jù)類型:具有方法'''# 練習(xí)1:# 創(chuàng)建一個(gè)貓類:屬性 品種、價(jià)格、顏色 方法--- 睡覺、吃魚、被擼# 創(chuàng)建一個(gè)對象對該類進(jìn)行測試,輸出改對象的所有信息class Cat: name = '喵星人' # 類屬性 # 構(gòu)造方法 def __init__(self,bread,color,price): # 實(shí)例屬性 self.bread = bread self.color = color self.price = price def sleep(self): print('我喜歡睡覺') def eat_fish(self): print('我喜歡吃魚') def bei_lu(self): print('我喜歡被主人擼')tom = Cat('星羅貓','白色',2000)jeck = Cat('貍花貓','漸變色',1500)print(tom.name)print(jeck.name)print('種類:{},顏色:{},價(jià)格:{}'.format(tom.bread,tom.color,tom.price))print('種類:{},顏色:{},價(jià)格:{}'.format(jeck.bread,jeck.color,jeck.price))tom.sleep()jeck.eat_fish()'''# 關(guān)于抽象的而理解:# 把相同的或相似的對象歸為一類的這個(gè)過程就是抽象,所以,抽象就是分析文件的方法;# 抽象程度基本原則:# 只關(guān)心主要問題,而不關(guān)系次要問題;# 只關(guān)心主要矛盾,爾不關(guān)系次要矛盾;# 只關(guān)心相同的東西,而不關(guān)心不通的東西;# 只關(guān)心問題是什么,能夠完成什么,而不關(guān)系怎么樣區(qū)完成。# 抽象的過程其實(shí)就是面向?qū)ο缶幊痰暮诵乃枷? 類和對象有什么區(qū)別?# - 類士抽象的概念,僅僅是模板,比如說'人’# - 對象是一個(gè)你能看得到、摸得著的具體實(shí)體,# 創(chuàng)建類和對象# python實(shí)現(xiàn)類的語法:# class ClassName:# '類的幫助信息' # 類文檔字符串# class_suit # 類體# 在class_suit里面就可以定義屬性、方法、實(shí)例屬性等。但一個(gè)類定義完成之后,就# 產(chǎn)生了一個(gè)類對象。類對象支持兩種操作:引用和實(shí)例化。引用操作是通過類對象區(qū)調(diào)用# 類種的屬性或者方法,而實(shí)例化是產(chǎn)生出一個(gè)類對象的實(shí)例,稱作實(shí)例對象。# 創(chuàng)建實(shí)例對象語法:# objectName = ClassName(args) # 其中args初始化參數(shù)列表# 訪問屬性# 可以使用. 來訪問對象的屬性# 舉例:'''class people: name = '人類' # 類屬性 def __init__(self,name,age): self.name = name # 實(shí)例屬性 self.age = ageliuze = people('劉澤',30) # 創(chuàng)建對象print(people.name) # 訪問類屬性print(liuze.name) # 訪問對象屬性'''# 該段代碼定義了一個(gè)people類,里面定義了name屬性# people.name 表示進(jìn)行引用操作,類對象區(qū)應(yīng)用類屬性# liuze.name 表示實(shí)例化操作,實(shí)例對象去引用實(shí)例屬性# python 種的類是由屬性和方法組成的,具體的劃分如下圖:''' 屬性 類屬性 實(shí)例屬性(私有) 內(nèi)置屬性類 方法 構(gòu)造方法 類方法 實(shí)例方法(私有) 靜態(tài)方法 內(nèi)置方法'''# 類屬性:類對象的屬性,如之前例子中 name = '人類'# 實(shí)例屬性:通過實(shí)例化對象后,對象可以使用的屬性,如print(liuze.name)# 私有屬性:在類中,兩個(gè)下劃線開頭,聲明該屬性屬于私有,不能在類的外部被使用或# 直接訪問,在類內(nèi)部的方法中使用時(shí) self.__private_attrs; 也可以使用object.# __className_attrName(對象名._類名_私有屬性名) 訪問屬性# 內(nèi)置屬性:python 類中系統(tǒng)默認(rèn)自帶的屬性# 內(nèi)置屬性如下:# _dict_:類的屬性(包含一個(gè)字典,由類的數(shù)據(jù)屬性組成)# _doc_ : 類的文檔字符串# _name_: 類名# _module_:類定義所在的模塊(類的全名是'_main_.className’),如果類位于一個(gè)# 導(dǎo)入模塊mymod中,那么className._module_ 等于mymod)# _bases_:類的所有父類構(gòu)成元素(包含了一個(gè)由所有父類組成的元組)'''# 創(chuàng)建一個(gè)人類,屬性:姓名、年齡、性別 使用構(gòu)造方法完成class People: # 我是People類,是類說明,只能放在類名下面 name = '好人' def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sexPerson1 = People('Michael',32,'formal')# 內(nèi)置屬性:python類中系統(tǒng)默認(rèn)自帶的屬性# 類名.內(nèi)置屬性print(People.__dict__) # 類屬性print(People.__doc__) # 類的文檔字符串, 類說明print(People.__name__) # 返回類名print(People.__module__) # 類定義所在模塊print(People.__base__) # 類的父類,如果沒有默認(rèn)就是object'''# 屬性、方法# 構(gòu)造方法:# 構(gòu)造方法是負(fù)責(zé)對象成員初始化工作,為實(shí)例變量(對象屬性)賦予合適的初始化值# 在python中構(gòu)造方法使用的是__init__()方法,當(dāng)創(chuàng)建了這個(gè)類的實(shí)例時(shí)就會(huì)# 調(diào)用該方法# self 是什么?# 在上頁P(yáng)PT的例子中,構(gòu)造方法中第一個(gè)形參為self,它代表類的實(shí)例。在python# 中,slef在定義類的方法時(shí)必須有一個(gè)參數(shù),且必須是第一個(gè)參數(shù),但我們在調(diào)用# 類的方法時(shí)不需要傳入相應(yīng)的參數(shù)。是否方法中存在self也是區(qū)分類的方法與普通的函數(shù)# 的一個(gè)標(biāo)識。# self 不是python 關(guān)鍵字,我們把它換成其它的也是可以正常執(zhí)行的。但建議用# self。如下:'''def __init__(this,name,age): # 可以改為this this.name = name this.age = age'''# 實(shí)例方法# 在類中最常定義的成員方法,它至少有一個(gè)參數(shù)并且必須以實(shí)例對象作為其第一個(gè)參數(shù),# 一般以名為'self’的變量作為第一個(gè)參數(shù)。(注意:不能通過類對象引用實(shí)例方法)# 在實(shí)例方法中,以兩個(gè)下劃線開頭,則表示改方法為私有方法,不能在類外部調(diào)用。在類# 的內(nèi)部調(diào)用方法: self.__private_methods,在外部調(diào)用方法:實(shí)例._方法名()# 舉例如下:'''class people: def __init__(self,name): self.name = name def getName(self): return self.name def __say(self,con): print(self.name+'說:'+con)liuze = people('劉澤')print(liuze.getName()) # 通過實(shí)例對象引用liuze._people__say('你好') # 外部調(diào)用私有方法'''# 類方法# 時(shí)類對象所擁有的方法,需要用修飾器“@classmethod”來標(biāo)識其它類方法,它能夠# 夠通過實(shí)現(xiàn)對象和類對象去訪問。類方法的用途就是可以對類屬性進(jìn)行修改。對于類方法,# 第一個(gè)參數(shù)必須是類對象,一般以'cls'作為抵押給參數(shù)。# 靜態(tài)方法:# 需要通過修飾器“@staticmethod”來進(jìn)行修飾,靜態(tài)方法不需要多定義參數(shù)。類和實(shí)例# 都能調(diào)用。'''class country: name = 'china' @classmethod def setName(cls,name): #類方法 cls.name = name @staticmethod def getName(): # 靜態(tài)方法 print(country.name)''''''# 屬性:類屬性、實(shí)例屬性、了內(nèi)置屬性# 方法:類方法、實(shí)例方法、靜態(tài)方法class People: name = '無名氏' # 類屬性 def __init__(self,name,age,sex): # 實(shí)例屬性 self.name = name self.age = age self.sex = sex def say(self): # 實(shí)例方法,類當(dāng)中的普通方法 print('我是實(shí)例方法 say() ') @classmethod # 修飾器,它下main的方法就是類方法 def sleep(cls): # 類方法的第一個(gè)參數(shù)默認(rèn)就是cls print('我是類方法 sleep() ') @staticmethod # 它下面的方法就是靜態(tài)方法 def goto_wc(): # 靜態(tài)方法不會(huì)帶默認(rèn)的參數(shù) print('我是靜態(tài)方法 goto_wc()')tom = People('湯姆',22,'男')# 1、可以通過 類和對象 訪問類屬性print(People.name)print(tom.name)# 2、只能通過對象 訪問實(shí)例屬性# print(People.age)print(tom.age)# 3、可以通過 類和對象 訪問內(nèi)置屬性,但是還值是不一樣的print(People.__dict__)print(tom.__dict__)# 4、可以通過 類和對象 訪問類方法print(People.sleep())print(tom.sleep())# 5、通過對象 訪問實(shí)例方法# People.say() # 通過類直接訪問時(shí),它會(huì)被當(dāng)作一個(gè)普通方法啊,所以需要對self傳參tom.say()# 6、可以通過 類和對象 訪問靜態(tài)方法People.goto_wc()tom.goto_wc()'''# 常用內(nèi)置方法:# 在 python 中有一些內(nèi)置的方法,這些方法命名都有比較特殊的地方(其方法名以2個(gè)下劃線)# 開始然后以2個(gè)下劃線結(jié)束。# 1、__init__(self,.....): 構(gòu)造方法,在生成對象時(shí)調(diào)用,可以用來進(jìn)行一些初始化# 操作,不需要顯示去調(diào)用,系統(tǒng)回默認(rèn)去執(zhí)行。構(gòu)造方法支持重載,如果用戶自己沒有重新定義構(gòu)# 造方法,系統(tǒng)就會(huì)自動(dòng)執(zhí)行默認(rèn)的構(gòu)造方法。# 2、__del__(self,......): 析構(gòu)方法,在釋放對象時(shí)調(diào)用,支持重載,可以在里面進(jìn)行一些釋# 放資源的操作,不需要顯示調(diào)用# 3、__str__(self,.......): 自定義實(shí)例輸出方法,寫好改方法后,替換實(shí)例默認(rèn)的輸出操作。# 4、__add__(self,......): 兩個(gè)實(shí)例的加法操作。# 5、__getattribute__(.....): 獲取實(shí)例屬性的值,柯直接結(jié)合對象使用。'''# 內(nèi)置方法class People: # 1、構(gòu)造方法,支持重載(使用最后一個(gè)) def __init__(self, name, age): self.name = name self.age = age # def __init__(self, name): # self.name = name # 2、析構(gòu)方法,作用時(shí)釋放資源 def __del__(self): print('我是析構(gòu)方法,作用是釋放資源') # 3、自定義輸出方法 def __str__(self): return '我是默認(rèn)的str實(shí)例輸出方法' # 4、兩個(gè)實(shí)例的加法操作 def __add__(self, other): return self.name + other.namezs = People('張三',20)tom = People('tom',15)print(zs+tom)print(zs)# del zs# print(zs.name)'''# 面向?qū)ο缶幊倘筇匦? 面向?qū)ο缶幊倘筇匦裕悍庋b,繼承和多態(tài)# 封裝:# 面向?qū)ο蟮某绦蛟O(shè)計(jì)中,某個(gè)類把所需要的數(shù)據(jù)(也可以說是類的屬性)和對數(shù)據(jù)的操作# (也可以說是類的行為)全部封裝在類中,分別稱為類的成員變量和方法(或成員函數(shù)),這# 種把成員變量和成員函數(shù)封裝在一起的編程特性稱為封裝。'''# 封裝: 數(shù)據(jù)封裝、方法封裝class People: # 1、構(gòu)造方法,支持重載(使用最后一個(gè)) def __init__(self, name, age,money): self.name = name self.age = age # 私有屬性:只能在類的內(nèi)部使用,類外部訪問不來(數(shù)據(jù)封裝) self.__money = money # 方法封裝 def get_money(self): return self.__money def set_money(self,m): self.__money = mzs = People('張三',20,100)zs.set_money(200)print('我叫{},我有{}塊錢!'.format(zs.name,zs.get_money()))'''# 繼承:# 繼承也指可以使用現(xiàn)有類的所有功能,并在無重新編寫原來的類的情況下對這些功能進(jìn)行擴(kuò)展# 多態(tài):# 多態(tài)指的是一類事務(wù)有多種形態(tài)。如序列類型有多種形態(tài):字符串,列表,元組;動(dòng)物有多種# 形態(tài):牛、狗、豬# 多態(tài)性是允許你將父對象設(shè)置稱為和一個(gè)或更多的他的子對象相等的技術(shù),賦值之后,父對象# 就可以根據(jù)當(dāng)前賦值給它的子對象的特性以不同的方式運(yùn)作。# 封裝分為數(shù)據(jù)封裝與方法封裝# 數(shù)據(jù)封裝即把對象的屬性具體的值隱藏起來,對外顯示的只是對象的屬性名。比如劉澤的名字,# 錢包里的錢等。# 方法封裝即對外只需要通過方法就能調(diào)用方法,而不選喲了解具體方法種的細(xì)節(jié)。比如洗衣機(jī)# 按洗衣的功能按鈕,就能進(jìn)行洗衣,我們不需要知道這個(gè)過程中的原理;在用支付寶進(jìn)行付款的時(shí)候,# 只需要在用的時(shí)候把二維碼給收款方或是掃一下收款方提供的二維碼就可以完成支付,不需要# 知道支付寶的支付接口,以及后臺處理數(shù)據(jù)的能力等。# 封裝的而作用:封裝數(shù)據(jù)的主要原因是保護(hù)隱私;封裝方法的而主要原因是隔離復(fù)雜度。# 封裝分為兩個(gè)層面:# 第一層面的封面:創(chuàng)建類和對象時(shí),分別創(chuàng)建兩種的名稱空間。只能通過類名加“.”或者obj# .的方式訪問里面的名字。# 第二層面的封裝,類種把某些屬性和方法隱藏起來,或者定義為私有,只在類的內(nèi)部使用,在類# 的外部無法訪問,或者留下少量的接口(函數(shù))供外部訪問# 當(dāng)我們定義一個(gè)class 的時(shí)候,可以從某個(gè)現(xiàn)有的class繼承屬性和方法,新的class# 稱為子類(Subclass),而被繼承的class稱為基類、父類或超類(Base class,Super# class)。如下圖:''' object Animal Plant Dog Cat Tree Flower'''# 在python中,object類時(shí)所有類的父類。Python3 中默認(rèn)都是繼承object ,稱為# 新式類;在python2中,不能指定繼承object類的類稱為經(jīng)典類。# 繼承的語法如下;# class 派生類名(基類名):# ...# 舉例:'''class Parent: # 定義父類 parentAttr = 100 def __init__(self): print('調(diào)用父類的構(gòu)造函數(shù)') def parentMethod(self): print('調(diào)用父類的方法')class Child(Parent): def __init__(self): print('調(diào)用子類構(gòu)造方法') def childMethod(self): print('調(diào)用子類方法')child_01 = Child()child_01.parentMethod() # 調(diào)用父類的方法print(child_01.parentAttr) # 調(diào)用父類的屬性child_01.childMethod() # 調(diào)用自己的方法# 繼承:一個(gè)類(子類)獲取另外一個(gè)類(父類)的屬性和方法的過程# 人類:name,age,sex 方法:say() sleep()# 學(xué)生: name、age、sex、class、id 方法:say() sleep() study()class People: def __init__(self,name,age,sex): #私有的方法和屬性是不能被繼承的 self.name = name self.age = age self.sex = sex def say(self): print('我是people類的say()方法。') def sleep(self): print('我是people類的sleep()方法。')class Student(People): # 父類是people # 當(dāng)子類由構(gòu)造方法的時(shí)候,子類必須實(shí)現(xiàn)父類的構(gòu)造方法 def __init__(self,name,age,sex,class_name,id): # 1.父類名.__init__() 必須傳self People.__init__(self,name,age,sex) # 2.super().__init__() 不需要傳self super().__init__(name,age,sex) # 3.super(子類,self).__init() super(Student,self).__init__(name,age,sex) self.class_name = class_name self.id = id def study(self): # 子類重寫父類方法,子類對象會(huì)優(yōu)先調(diào)用自己方法 print('study()!??!') def say(self): print('我是學(xué)生類中的say()!!!1')zs = Student('張三',21,'男','火箭班','1班')print(zs.class_name,zs.id)zs.sleep()zs.say()zs.study()'''# isinstance() 及 issubclass()# python 與其他語言不同點(diǎn)在于,當(dāng)我們定義一個(gè)class 的時(shí)候,我們實(shí)際上就定義了一個(gè)# 數(shù)據(jù)類型。我們定義的數(shù)據(jù)類型和 Python 自帶的數(shù)據(jù)類型,比如: str、list、dict沒什么# 兩樣。# python 有兩個(gè)判斷繼承的函數(shù): isinstance(obj,Class)用于檢查實(shí)例類;# issubclass(sub,sup)用于檢查類繼承。# python 中的繼承特定# 1)在 Python 中,如果父類和子類都重新定義構(gòu)造方法__init__(),在進(jìn)行子類實(shí)例化的# 時(shí)候,子類的構(gòu)造方法不會(huì)自動(dòng)調(diào)用父類的構(gòu)造方法,必須在子類中顯示調(diào)用。# 2)如果需要在子類中調(diào)用父類的方法:需要以 父類名.方法 這種方式調(diào)用,以這種方式# 調(diào)用的時(shí)候,注意:要傳遞self參數(shù)過去;另一種方法啊是使用super(),直接使用super()# .xxx 或 super(Class,self).xxx# 3) Python 總是首先查找對應(yīng)類型的方法,如果它不能在派生類中找到對應(yīng)的方法,它才# 開始到基類中逐個(gè)查找。(現(xiàn)在本類中查找調(diào)用方法,找不到才去基類中找)# 4)對于繼承關(guān)系,子類繼承父類所有的共有的屬性和方法,可以在子類中通過父類名來調(diào)用,# 而對于私有的屬性和方法,子類時(shí)不進(jìn)行繼承的,因此子類中無法通過父類名來訪問的。# 5)python中支持多繼承,能夠讓又給子類有多個(gè)父類。如果有多個(gè)父類,多個(gè)父類名之間# 用都好隔開。# class SubClass(SuperClass1,SuperClass2)# 如果SubClass沒有重新定義構(gòu)造方法,它自動(dòng)調(diào)用第一個(gè)父類的構(gòu)造方法,以第一個(gè)父類# 為中心。# 如果Subclass 沒有定義構(gòu)造方法,需要顯示去調(diào)用父類的構(gòu)造方法,此時(shí)調(diào)用那個(gè)父類# 的構(gòu)造方法由你自己決定;若SubClass 沒有重新定義構(gòu)造方法,則只會(huì)執(zhí)行第一個(gè)父類的構(gòu)造# 方法。并且若SuperClass1和SuperClass2中有同名的方法,通過子類的實(shí)例化對象去# 調(diào)用改方法時(shí)嗲用的時(shí)第一個(gè)父類中的方法。# 實(shí)例:'''class UniversityMember: def __init__(self,name,age): self.name = name self.age = age def getName(self): return self.nameclass Student(UniversityMember): def __init__(self,name,age,sno,mark): UniversityMember.__init__(self,name,age) # 注意顯示調(diào)用父類構(gòu)造方法 self.sno = sno self.mark = mark def getMark(self): return self.mark # 代碼解釋:大學(xué)中的每個(gè)成員都有姓名和名稱,而學(xué)生有學(xué)號和分?jǐn)?shù)2個(gè)屬性,大學(xué)成員 # 為父類,學(xué)生為子類# 多繼承:一個(gè)子類可以有多個(gè)父類# 人類、動(dòng)物 --- 學(xué)生class People: def __init__(self, name): self.name = name def say(self): print('我是people類')class Animal: def __init__(self, age): self.age = age def say(self): print('我是Animal類')class Student(People, Animal): # 多繼承 # 當(dāng)父類中有同名的方法時(shí),按照繼承的先后順序調(diào)用 # 實(shí)現(xiàn)多個(gè)父類構(gòu)造方法(非必須實(shí)現(xiàn)) def __init__(self, name, age, id): People.__init__(self,name) Animal.__init__(self,age) self.id = id # # def say(self): # print('我是一個(gè)好學(xué)生')zs = Student('張三', 16, 11)print(zs.name)print(zs.age)print(zs.id)zs.say()'''# 抽 象 類# 抽象類是包含抽象方法的類,而抽象方法不包含任可實(shí)現(xiàn)的代碼,只能在其子類中實(shí)現(xiàn)抽象# 函數(shù)的代碼。# 為什么要有抽象的類?# 如果說類是從一堆對象中抽象相同的內(nèi)容而來的,那么抽象類就是從一堆類中抽取形同# 內(nèi)容來的,內(nèi)容包括數(shù)據(jù)屬性和函數(shù)屬性。# 比如我們有香蕉的類,有蘋果的類,有桃子的類,從這些類中抽取相同的內(nèi)容就是水果# 這個(gè)抽象的類,你吃水果時(shí),要么是吃一個(gè)具體的香蕉,要么吃一個(gè)具體的桃子,你永遠(yuǎn)無法# 吃到一個(gè)叫做水果的食物。# 在定義抽象時(shí)需要在類定義中加入如下代碼:__metaclass__ABCmeta,即指定該類# 的元類時(shí)ABCmeta。所謂元類就是創(chuàng)建類的類。# 在定義抽象方法時(shí)需要在前面加入如下代碼:@abstractmethod 因?yàn)槌橄蠓椒ú话? 任何可實(shí)現(xiàn)的代碼,因此其函數(shù)體通常使用pass# 抽象類實(shí)現(xiàn)舉例;'''from abc import ABCMeta, abstractmethodclass People: __metaclass__ = ABCMeta @abstractmethod def set_name(self): passclass Student(People): def set_name(self, name): # 參數(shù)個(gè)數(shù)不同,重載 print('Student,set_name = %s' % name) # 抽象類:# 1.必須包含抽象方法# 2.抽象方法只聲明不實(shí)現(xiàn)# 3.抽象類就是用來被繼承的,子類必須實(shí)現(xiàn)父類的抽象方法。from abc import abstractmethod, ABCMetaclass Animal(metaclass=ABCMeta): # 這種方式子類繼承Animal后必須實(shí)現(xiàn) # __metclass__ = ABCMeta # 定義抽象類,這種方式子類繼承后不必須實(shí)現(xiàn)抽象方法【不推薦】 def __init__(self, name): self.name = name @abstractmethod # 定義抽象方法修飾器 def say(self): # 只聲明不實(shí)現(xiàn) passclass Cat(Animal): def say(self): print('實(shí)現(xiàn)父類抽象say()方法') def eat(self): print('貓喜歡吃魚!')tom = Cat('湯姆')print(tom.name)tom.eat()tom.say()'''# 多態(tài)指的時(shí)一類事務(wù)具有多種形態(tài),只有存在父子類關(guān)系才會(huì)讓一類事物具有多種不# 同的形態(tài),因而多態(tài)的實(shí)現(xiàn)過程中,經(jīng)常會(huì)使用抽象類。# 舉例:# 1、序列類型有多種形態(tài):字符串,列表,元組# 2、動(dòng)物有多種形態(tài):豬,狗,牛# 多態(tài)性:# 多態(tài)性是指具有不通功能的函數(shù)可以使用相同的函數(shù)名,這樣就可以用一個(gè)函數(shù)名# 調(diào)用不同的內(nèi)容的函數(shù)。在面向?qū)ο蠓椒ㄖ幸话闶沁@樣表述多態(tài)性;向不通的對象發(fā)送# 同一條消息,不通對象在接收時(shí)會(huì)產(chǎn)生不同的行為(即方法)。也就是說,每個(gè)對象可# 以用自己的方式去響應(yīng)共同的消息。所謂消息,就是調(diào)用函數(shù),不同的行為就是指不同# 的實(shí)現(xiàn),即執(zhí)行不同的函數(shù)。# 舉例:# 內(nèi)置函數(shù)len(object),len函數(shù)不僅可以計(jì)算字符串的長度,還可以計(jì)算列表、# 元組等對象中的數(shù)據(jù)個(gè)數(shù),這里在運(yùn)行時(shí)通過擦拭農(nóng)戶類型確定其具體的計(jì)算過程,正# 是多態(tài)的一種體現(xiàn)。# 舉例編碼:# 多態(tài):一類事物具有多種形態(tài)# 多態(tài)性:只具有不同功能的函數(shù)可以使用相同的函數(shù)名'''import abcclass File(metaclass=abc.ABCMeta): # 同一類事物:文件 @abc.abstractmethod def click(self): pass# 實(shí)現(xiàn)多態(tài)class Text(File): # 文件的形態(tài)之一:文本文件 def click(self): print('open file')# 實(shí)現(xiàn)多態(tài)class ExeFile(File): # 文件的形態(tài)之一:可執(zhí)行文件 def click(self): print('execute file')# 多態(tài)性def openFile(obj): obj.click()txt = Text()exe = ExeFile()# 調(diào)用openFile()實(shí)現(xiàn)多態(tài)性openFile(txt)openFile(exe)'''
|