python面向?qū)ο螅ㄏ拢?/h2>

一、面向?qū)ο?,這個對象到底是什么?

這個對象不是python中的實(shí)例,python中我們把一個類的實(shí)例也叫做對象,這種對象嚴(yán)格的說應(yīng)該是面向?qū)ο蟮木幊虒?shí)現(xiàn)(OOP)中的對象,面向?qū)ο缶幊?,也不是面向類的?shí)例編程。對象的定義是人們要進(jìn)行研究的任何事物,從最簡單的整數(shù)到復(fù)雜的飛機(jī)等均可看作對象,它不僅能表示具體的事物,還能表示抽象的規(guī)則、計劃或事件。也有的定義為“一切都是對象”然而面向?qū)ο笠膊荒芎唵蔚牡葍r理解成面向任何事物編程,面對一切編程?開玩笑,呵呵。

因此面向?qū)ο筮@個對象,指的是客體。所謂客體是指客觀存在的對象實(shí)體和主觀抽象的概念。

二、面向?qū)ο蟪绦蛟O(shè)計的由來

1、編程語言的發(fā)展

程序設(shè)計這東西一開始出現(xiàn),是按照人類的語言習(xí)慣,將盡量符合人類語言的語法結(jié)構(gòu)來描述要實(shí)現(xiàn)的功能,然后通過各種軟件環(huán)境[XX語言編譯器、XX語言解釋器]將這樣符合人類語言的語法編譯或者解釋成計算機(jī)能認(rèn)識和執(zhí)行的語言去執(zhí)行并實(shí)現(xiàn)功能的過程,于是出現(xiàn)了高級語言。

2、面向過程的程序設(shè)計

高級語言出現(xiàn)之初,程序設(shè)計的思路,也是參考了人類解決問題的思路;

遇到一個問題,人類習(xí)慣性的思維方式是第一步做什么、第二步做什么、緊接著做什么,這樣按照一定的步驟一直到實(shí)現(xiàn)最終想要的功能。

這樣的按照事情/功能的處理過程和步驟來進(jìn)行程序的設(shè)計和開發(fā)的過程,是一種解決問題的思路,我們稱之為:面向過程的程序設(shè)計

3、面向過程程序設(shè)計的缺陷

面向過程的程序設(shè)計發(fā)展了一定的時間之后,我們發(fā)現(xiàn)出現(xiàn)了一個非常重要的問題,如果僅僅是處理某一個功能的流程而言非常適合,但是如果一旦涉及到業(yè)務(wù)過程比較復(fù)雜的系統(tǒng)來說的話,面向過程的思路設(shè)計的程序出現(xiàn)了大量的代碼冗余、同時不同的功能之間的沖突隨著系統(tǒng)功能的增多沖突越來越多,另外當(dāng)系統(tǒng)中的某些功能如果需要升級或者改動,會涉及到大量的代碼的修改和功能的影響造成維護(hù)的不方便

4、面向?qū)ο?/p>

這時候,一幫大佬們圍坐在一起,開始商量怎么樣讓我們的程序更加適合開發(fā)結(jié)構(gòu)完整、流程復(fù)雜的系統(tǒng)項(xiàng)目呢!

有人就提出了,我們的程序,其實(shí)一直都是在模擬符合正常人的思維邏輯習(xí)慣的,小功能的處理就像我們處理一件小事一樣,可以按照步驟進(jìn)行處理,也就是按照面向過程的設(shè)計思路進(jìn)行處理;

三、首先看看面向?qū)ο蟮娜筇卣鳎?/b>

封裝:將對象的敏感的信息封裝在對象的內(nèi)部,不讓外界直接訪問,提高數(shù)據(jù)的安全性

繼承:通過繼承關(guān)系,梳理對象和對象之間的關(guān)系,同時提高了程序設(shè)計功能的強(qiáng)大的擴(kuò)展性和代碼的復(fù)用性

多態(tài):程序在運(yùn)行過程中,實(shí)時根據(jù)不同的數(shù)據(jù)執(zhí)行不同的處理邏輯展現(xiàn)不同的狀態(tài),讓程序的功能更加的完善健壯

因此面向?qū)ο竽軐?shí)現(xiàn)人們追求的系統(tǒng)可維護(hù)性,可擴(kuò)展性,可重用性。面向?qū)ο笫且环N編程思想,起初,“面向?qū)ο蟆笔菍V冈诔绦蛟O(shè)計中采用封裝、繼承、多態(tài)等設(shè)計方法,但面向?qū)ο蟮乃枷胍呀?jīng)涉及到軟件開發(fā)的各個方面,比如現(xiàn)在細(xì)分為了面向?qū)ο蟮姆治?OOA),面向?qū)ο蟮脑O(shè)計(OOD),面向?qū)ο蟮木幊虒?shí)現(xiàn)(OOP)

四、面對對象編程,分為幾個步驟?

面向?qū)ο笫且环N思想,他讓我們在分析和解決問題時,把思維和重點(diǎn)轉(zhuǎn)向現(xiàn)實(shí)中的客體中來,然后通過工具理清這些客體之間的聯(lián)系,最后用面向?qū)ο蟮恼Z言實(shí)現(xiàn)這種客體以及客體之間的聯(lián)系。它分為面向?qū)ο蟮姆治?OOA),面向?qū)ο蟮脑O(shè)計(OOD),面向?qū)ο蟮木幊虒?shí)現(xiàn)(OOP)三個大的步驟。

1、首先是分析需求,先不要思考怎么用程序?qū)崿F(xiàn)它,先分析需求中穩(wěn)定不變的客體都是些什么,這些客體之間的關(guān)系是什么。

2、把第一步分析出來的需求,通過進(jìn)一步擴(kuò)充模型,變成可實(shí)現(xiàn)的、符合成本的、模塊化的、低耦合的模型。

3、使用面向?qū)ο蟮膶?shí)現(xiàn)模型

五、面向過程到面向?qū)ο笏季S如何轉(zhuǎn)變?

當(dāng)我們習(xí)慣了面向過程編程時,發(fā)現(xiàn)在程序過程中到處找不到需要面向?qū)ο蟮牡胤?,最主要的原因,是思維沒有轉(zhuǎn)變。程序員通常在拿到一個需求的時候,第一個反應(yīng)就是如何實(shí)現(xiàn)這個需求,這是典型的面向過程的思維過程,而且很快可能就實(shí)現(xiàn)了它。而面向?qū)ο?,面對的卻是客體,第一步不是考慮如何實(shí)現(xiàn)需求,而是進(jìn)行需求分析,就是根據(jù)需求找到其中的客體,再找到這些客體之間的聯(lián)系。因此面向過程和面向?qū)ο蟮乃季S轉(zhuǎn)變的關(guān)鍵點(diǎn),就是在第一步設(shè)計,拿到需求后,一定先不要考慮如何實(shí)現(xiàn)它,而是通過建模,然后按照模型去實(shí)現(xiàn)它。這種思路的轉(zhuǎn)變,可能需要個過程。

六、Python3面向?qū)ο?/b>

Python從設(shè)計之初就已經(jīng)是一門面向?qū)ο蟮恼Z言,正因?yàn)槿绱?,在Python中創(chuàng)建一個類和對象是很容易的。下面將詳細(xì)介紹Python的面向?qū)ο缶幊獭?/p>

如果你以前沒有接觸過面向?qū)ο蟮木幊陶Z言,那你可能需要先了解一些面向?qū)ο笳Z言的一些基本特征,在頭腦里頭形成一個基本的面向?qū)ο蟮母拍睿@樣有助于你更容易的學(xué)習(xí)Python的面向?qū)ο缶幊獭?/p>

接下來我們先來簡單的了解下面向?qū)ο蟮囊恍┗咎卣鳌?/p>

面向?qū)ο蠹夹g(shù)簡介

(Class):用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實(shí)例。

類變量:類變量在整個實(shí)例化的對象中是公用的。類變量定義在類中且在函數(shù)體之外。類變量通常不作為實(shí)例變量使用。

數(shù)據(jù)成員:類變量或者實(shí)例變量用于處理類及其實(shí)例對象的相關(guān)的數(shù)據(jù)。

方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進(jìn)行改寫,這個過程叫方法的覆蓋(override),也稱為方法的重寫。

實(shí)例變量:定義在方法中的變量,只作用于當(dāng)前實(shí)例的類。

繼承:即一個派生類(derived class)繼承基類(base class)的字段和方法。繼承也允許把一個派生類的對象作為一個基類對象對待。例如,有這樣一個設(shè)計:一個Dog類型的對象派生自Animal類,這是模擬"是一個(is-a)"關(guān)系(例圖,Dog是一個Animal)。

實(shí)例化:創(chuàng)建一個類的實(shí)例,類的具體對象。

方法:類中定義的函數(shù)。

對象:通過類定義的數(shù)據(jù)結(jié)構(gòu)實(shí)例。對象包括兩個數(shù)據(jù)成員(類變量和實(shí)例變量)和方法。

和其它編程語言相比,Python在盡可能不增加新的語法和語義的情況下加入了類機(jī)制。

Python中的類提供了面向?qū)ο缶幊痰乃谢竟δ埽侯惖睦^承機(jī)制允許多個基類,派生類可以覆蓋基類中的任何方法,方法中可以調(diào)用基類中的同名方法。

對象可以包含任意數(shù)量和類型的數(shù)據(jù)。

類定義

語法格式如下:

Class類名稱:

Pass

類的組成:類名稱、屬性、方法

類實(shí)例化后,可以使用其屬性,實(shí)際上,創(chuàng)建一個類之后,可以通過類名稱訪問其屬性。

類對象

類的對象支持兩種操作:屬性引用和實(shí)例化。

屬性引用使用和Python中所有的屬性引用一樣的標(biāo)準(zhǔn)語法:obj.name。

類的對象創(chuàng)建后,類命名空間中所有的命名都是有效屬性名。U = User

創(chuàng)建對象的過程:

首先,用創(chuàng)建的類型的__new__()函數(shù)創(chuàng)建對象

其次,調(diào)用__init__()函數(shù)初始化對象的數(shù)據(jù)

Self關(guān)鍵字

self代表對象本身,可以是任意變量,則必須放在第一個參數(shù)位,但是規(guī)范要求必須使用self。

類的方法與普通的函數(shù)只有一個特別的區(qū)別——它們必須有一個額外的第一個參數(shù)名稱,按照慣例它的名稱是self。

類的方法

在類的內(nèi)部,用def來定義一個方法,與一般函數(shù)定義不同,類方法必須包含參數(shù)self,且為第一個參數(shù),self代表的是類的實(shí)例。

面向?qū)ο蟮奶卣鳌庋b

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

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

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

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

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

給每個屬性提供set/get方法,在方法中添加限制條件

高級封裝

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

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

對方法的封裝

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

再說各種變量

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

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

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

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

面向?qū)ο蟮奶卣鳌^承

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

繼承的語法:

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

pass

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

父類:被繼承的類,也稱為基類、超類

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

子類繼承父類,體現(xiàn)的時A is a B的關(guān)系

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

繼承鏈

A繼承B,B繼承C,C繼承D

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

那么問題又來了,多繼承呢?

·是否可以繼承多個類

·如果繼承的多個類每個類中都定了相同的函數(shù),那么那一個會被使用呢?

1、Python的類可以繼承多個類,Java和C#中則只能繼承一個類

2、Python的類如果繼承了多個類,那么其尋找方法的方式有兩種,分別是:

深度優(yōu)先廣度優(yōu)先


·當(dāng)類是經(jīng)典類時,多繼承情況下,會按照深度優(yōu)先方式查找

·當(dāng)類是新式類時,多繼承情況下,會按照廣度優(yōu)先方式查找

經(jīng)典類和新式類,從字面上可以看出一個老一個新,新的必然包含了跟多的功能,也是之后推薦的寫法,從寫法上區(qū)分的話,如果當(dāng)前類或者父類繼承了object類,那么該類便是新式類,否則便是經(jīng)典類。

經(jīng)典類:首先去A類中查找,如果A類中沒有,則繼續(xù)去B類中找,如果B類中么有,則繼續(xù)去D類中找,如果D類中么有,則繼續(xù)去C類中找,如果還是未找到,則報錯

新式類:首先去A類中查找,如果A類中沒有,則繼續(xù)去B類中找,如果B類中么有,則繼續(xù)去C類中找,如果C類中么有,則繼續(xù)去D類中找,如果還是未找到,則報錯

注意:在上述查找過程中,一旦找到,則尋找過程立即中斷,便不會再繼續(xù)找了

python中,一個類型,可以同時繼承多個類型,同時擁有所有繼承類型的所有公開的屬性和方法

備注:在進(jìn)行代碼設(shè)計的過程中,可能會出現(xiàn)多繼承,所以盡量不要在父類中定義相同名稱的屬性或者方法

備注2:如果父類中出現(xiàn)了相同名稱的屬性和方法,在使用的時候子類調(diào)用時會優(yōu)先繼承優(yōu)先調(diào)用。

方法重寫:

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

擴(kuò)展:子類中,訪問父類的屬性和方法:

class User(Person):

def __init__(self, name, age):

#直接通過父類的類名稱調(diào)用父類的屬性和方法

Person.__init__(name, age)

#通過super()來調(diào)用父類的屬性和方法

super().__init__(name, age)

面向?qū)ο蟮奶卣鳎憾鄳B(tài)

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

態(tài)即多種形態(tài),在運(yùn)行時確定其狀態(tài),在編譯階段無法確定其類型,這就是多態(tài)。Python中的多態(tài)和Java以及C++中的多態(tài)有點(diǎn)不同,Python中的變量是弱類型的,在定義時不用指明其類型,它會根據(jù)需要在運(yùn)行時確定變量的類型(個人覺得這也是多態(tài)的一種體現(xiàn)),并且Python本身是一種解釋性語言,不進(jìn)行預(yù)編譯,因此它就只在運(yùn)行時確定其狀態(tài),故也有人說Python是一種多態(tài)語言。在Python中很多地方都可以體現(xiàn)多態(tài)的特性,比如內(nèi)置函數(shù)len(object),len函數(shù)不僅可以計算字符串的長度,還可以計算列表、元組等對象中的數(shù)據(jù)個數(shù),這里在運(yùn)行時通過參數(shù)類型確定其具體的計算過程,正是多態(tài)的一種體現(xiàn)。

Python以它這種獨(dú)有的方式體現(xiàn)多態(tài)的根本原因我覺得有兩點(diǎn):

1)Python是解釋性語言;

2)Python中變量是弱類型的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容