复习面向对象
?
1、面向過程編程
????核心是”過程“二字,過程指的是解決問題的步驟,即先干什么再干什么
????基于該思想編寫程序就好比在編寫一條流水線,是一種機械式的思維方式
????優點:復雜的問題流程化、進而簡單化
????缺點:可擴展性差
?
2、面向對象
????核心”對象“二字,對象指的是特征與技能的結合體,
????基于該思想編寫程序就好比在創造一個世界,你就是這個世界的上帝,是一種
????上帝式的思維方式
????優點:可擴展性強
????缺點:編程的復雜度高于面向過程
?
對象與類
1、對象是特征與技能的結合體,那類就是一系列對象相同的特征與技能的結合體
2、在現實世界中:一定先有對象,后來隨著人類文明的發展總結出的類;對象是具體存在的,而類只是一種抽象概念
3、在程序中,務必保證:先定義類,后調用類來產生對象
#根據現實世界中的對象歸納現實世界的類,然后在程序中定義類,之后調用這個定義的類才產生程序中的對象
?
程序中的類
class OldboyStudent:? #用駝峰體表示類名,?變量名不推薦駝峰體
????# 用變量表示特征
??? school="Oldboy"?
????#? 用函數表示技能
??? def learn(self):
??????? print('is learning...')
??? def choose(self):
??????? print('choose course...')?
注意:在定義類的階段會立刻執行類體內的代碼,然后將產生的名字存放于類名稱空間中
#名稱空間用字典存數據
print(OldboyStudent.__dict__)? # .?后面的是屬性
?
調用類發生哪些事:
1、首先會產生一個空對象stu1
2、會自動觸發類內部的__init__函數
3、然后將空對象stu1連同調用類時括號內的參數組成(stu1,"馬冬梅",18,'female'),將這四個參數一起傳給__init__函數
?
stu1=OldboyStudent("馬冬梅",18,'female')? #OldboyStudent.__init__(stu1,"馬冬梅",18,'female')
stu2=OldboyStudent("甜蜜蜜",21,'male') #OldboyStudent.__init__(stu2,"甜蜜蜜",21,'male')
stu3=OldboyStudent("原石開",22,'male')
?
print(stu1.name,stu1.age,stu1.sex)
# .左邊一定是一個名稱空間。.右邊是屬性
?
對象的使用
調用類---》產生類的對象,該對象也可以稱為類的一個實例,調用類的過程也稱為類的實例化
stu1=OldboyStudent('李三胖',18,'male') #OldboyStudent.__init__(stu1,'李三胖',18,'male')
stu2=OldboyStudent('王大炮',28,'male')
?
先在對象的名稱空間中查找,若查不到接著去類的名稱空間中查找,若依然查不到則報錯,不會去全局名稱空間中查找。
print(stu1.school)? #但前綴,只在對象及類的名稱空間查找
print(school)? #不帶前綴,查的是全局名稱空間中的名字
?
類內部定義的變量是給所有對象共享,所有對象指向的都是同一個內存地址
print(id(stu1.school))
print(id(stu2.school))
print(id(OldboyStudent.school))?? #以上三者的id一致
?
類內部定義的函數,類可以使用,但類來用的時候就是一個普通函數,普通函數有幾個參就傳幾個參數
print(OldboyStudent.learn)
OldboyStudent.learn(123)
?
類內部定義的函數,其實是給對象使用的,而且是綁定給對象用,綁定給不同的對象就是不同的綁定方法(bound method)
print(stu1.learn)
print(stu2.learn)
綁定方法的特殊之處在于,誰來調用,就會將誰當作第一個參數自動傳入
?
一切皆對象:
類與類型是一個概念(在python3中,統一了類與類型的概念)
平時用的那些類型,全都是類
?
類與對象總結:
1.類的實例化:調用類產生對象的過程稱為類的實例化,實例化的結果是一個對象,或稱為一個實例
實例化做了三件事
a、先產生一個空對象
b、自動觸發類內部__init__函數的執行
c、將空對象,以及調用類括號內傳入的參數,一同傳給__init__,為對象定制獨有的屬性
?
2.對象的操作
用對象名.屬性名進行操作
?
3.對象屬性的查找順序:先找對象自己的名稱空間----》類的名稱空間
a.類的數據屬性:是給對象用的,而且直接共享給所有對象用的,內存地址都一樣
b.類的函數屬性:也是給對象用,但是綁定給對象用的,綁定到不同的對象就是不同的
綁定方法,內存地址都不一樣,但其實只想都是同一個功能
?
4.綁定方法的特殊之處:
a.綁定給誰就應該由誰來調用,
b.誰來調用就會把誰當做第一個參數傳入
?
5.一切皆對象:在python3中統一了類與類型的概念,類即類型
?
注意:
1、類中最常見的就是變量與函數的定義,并不是說一定要定義出變量與函數
2、程序中類并不完全等同于現實世界中的類,即可以是現實世界中存在的,也可是不存在的。
3、__init__方法
??? a.該方法內可以有任意的python代碼;主要用于完成初始化,也可以有其他功能
??? b.一定不能有返回值
?
繼承
面向對象的三大特性:繼承,封裝,多態
1、什么是繼承?
????繼承一種新建類的的方式,在python中支持一個兒子繼承多個爹。
????新建的類稱為子類或者派生類,父類又可以稱為基類或者超類;子類會”遺傳“父類的屬性。
2、為什么要用繼承
????減少代碼冗余
3、怎么用繼承
class ParentClass1:
??? pass
class ParentClass2:
??? pass
class Subclass2(ParentClass1,ParentClass2):
??? pass
print(Subclass2.__bases__)? #查父類,結果用元組形式顯示
#?在python2中有經典類與新式類之分
#?在python3中全都為新式類
繼承是類和類之間的關系,尋找這種關系需要先抽象再繼承
?
基于繼承再看屬性查找:
先找自己內部,然后去類中就找,不會直接找到父類,即不是就近尋找
?
派生
派生:子類定義自己新的屬性,如果與父類同名,以子類自己的為準
?
在子類派生出的新方法中重用父類的功能
方式一:指名道姓地調用(其實與繼承沒有什么關系的)
用類名直接調用
?
方式二:super()調用(嚴格依賴于繼承)
super()的返回值是一個特殊的對象,該對象專門用來調用父類中的屬性
了解:在python2中,需要super(自己的類名,self)
?
方式一和方式二不能混用
?
經典類與新式類
1、新式類:
????繼承object的類,以及該類的子類,都是新式類。
????在python3中,如果一個類沒有指定繼承的父類,默認就繼承object;所以說python3中所有的類都是新式類
?
2、經典類(只有在python2才區分經典類與新式類):
????沒有繼承object的類,以及該類的子類,都是經典類
?
在多繼承背景下的屬性查找
a.?非菱形時,經典型和新式型的查找順序一致,從左至右一條條找
經典類:深度優先
在python2中,class Teacher:為經典類
2、新式類:廣度優先
在python3中,class Teacher:為新式類 (自動加父類object)
只有新式類中有F.mro(),將查找關系顯示成列表, mro()為內置方法
?
super()依賴繼承
super()會嚴格按照mro列表從當前查找到的位置繼續往后查找
?
組合
解決類與類之間代碼冗余問題有兩種解決方案:1、繼承?2、組合
1、繼承:描述的是類與類之間,什么是什么的關系
2、組合:描述的是類與類之間的關系,是一種什么有什么關系;一個類產生的對象,該對象擁有一個屬性,這個屬性的值是來自于另外一個類的對象
組合不屬于繼承
類的使用將變量及處理其的函數捆綁起來
繼承是強耦合,組合是解耦合
?
如何封裝以及封裝的目的
1、什么是封裝:
裝就是把一堆屬性存起來,封的概念就把這些屬性給隱藏起來
強調:封裝單從字面意思去看等同于隱藏,但其實封裝絕對不是單純意義的隱藏
?
2、如何用封裝
如何把屬性隱藏起來,就在屬性前面加上__開頭(注意不要加__結尾)
注意:
a、其實這種隱藏只是一種語法上的變形,對外不對內
為一個屬性名加__開頭(注意不要加__結尾),會在類定義階段將屬性名統一變形:_自己的類名__屬性名
b、這種語法意義上變形,只在類定義階段發生一次,類定義之后,新增的__開頭的屬性都沒有變形的效果
c、如果父類不想讓子類覆蓋自己的方法,可以在方法名前加__開頭
?
?
3、為什么要用封裝
a、封裝數據屬性的目的:把數據屬性封裝起來,然后需要開辟接口給類外部的使用者使用,好處是我們可以在接口之上添加控制邏輯,從而嚴格空間訪問者對屬性的操作
b、封裝函數屬性的目的:為了隔離復雜度
c、封裝的終極奧義:明確地區分內外,對外是隱藏的,對內是開放的
?
封裝的property
用@調用
將方法偽裝成數據屬性!
@name.setter #obj.name='EGON' # @property裝飾的函數可以調用setter及deleter
setter用于該,deleter用于刪
property, classmethod和staticmethod為面向對象中的三大函數
用裝飾器property將數據屬性藏起來,進行查改刪操作,用戶無感
?
多態
什么是多態:多態指的是同一種事物多種形態
?
為什要用多態:用基類創建一套統一的規則,強制子類去遵循(使用抽象類實現),這樣便可以在不用考慮對象具體類型的前提下而直接使用對象下的方法。多態在程序中表現可以是繼承,但單純意義傷的繼承無法讓父類嚴格限制子類。
?
多態性:可以在不用考慮對象具體類型的前提下而直接使用對象下的方法
?
如何用多態
import abc #abstract class
class Animal(metaclass=abc.ABCMeta):
??? @abc.abstractmethod
??? def eat(self):
?? ?????pass
??? @abc.abstractmethod
??? def drink(self):
??????? pass
??? @abc.abstractmethod
??? def run(self):
??????? pass
??? @abc.abstractmethod
??? def bark(self):
??????? pass
創建一個虛擬父類用來限定規則,子類必須攜帶父類所有的方法!
?
鴨子類型
即程序員中默認的類型規定,
多個類有相同功能,不用管類是什么,記憶一套功能即可調用全部類
?
classmethod和staticmethod
1?綁定方法:
??在類內部定義的函數,默認就是給對象來用,而且是綁定給對象用的,稱為對象的綁定方法。? #什么裝飾器都不加
??綁定對象的方法特殊之處:應該由對象來調用,對象來調用,會自動將對象當作第一個參數傳入。
??綁定到類的方法特殊之處:應該由類來調用,類來調用,會自動將類當作第一個參數傳入。? #加classmethod裝飾器
總的來說,類中的函數可和對象綁定,可和類綁定(classmethod),也可隨都不綁定(statismethod)
?
staticmethod:非綁定方法,就是一個普通函數
特性:既不跟類綁定,也不跟對象綁定,這意味著誰都能用;誰來用都是一個普通函數,也就是說沒有自動傳值的特性了
?
classmethod:類綁定方法
特性:跟類綁定,調用該方法,會把類自動傳遞過去,一般用于在方法中實例化
?
轉載于:https://www.cnblogs.com/yangli0504/p/9146802.html
總結
- 上一篇: 腾讯云服务器部署FTP
- 下一篇: SAPPHIRE NOW阿里云 - 国内