python(十)面向對象編程

1,類與對象
java

類,是函數的更高級抽象。它描述的是一類事物具備的廣泛特性,而函數則是描述這些廣泛特性中的某一個點。python

好比說對於車來講,有各類各樣的車,車也有各類各樣的功能和屬性。若是採用函數來抽象,那麼若是要完整的抽象一輛車出來,那麼會須要不少函數相互配合,固然這其中一定少不了全局變量。採用函數的方式來抽象車的話,會有一個弊端,就是時隔好久以後,你能夠記不起來這輛車是由哪些函數和全局變量抽象而來的。程序員

因而面向對象編程,也就是類的出現,解決了這個問題。編程

類,抽象的是車這一類物體,描述它們的共有屬性和功能,而後由該類衍生而來的子類又具備各自特有的屬性和功能,同時,在類的定義中,咱們把須要描述該類事物所必須的方法(功能)和屬性,集中到一個「類」中,這樣你永遠不會忘記,這輛車是怎麼來的。eclipse

那麼,相對於類而言,對象則是類的一個具體的個體。好比說,車中有自行車,那自行車又有不少中,那你說的這個自行車究竟是那一個呢?這就須要一個實實在在的「東西」來表示,在面向對象中,這個「東西」就是對象。也就是說,對象是類的一個實例!編程語言

2,建立類函數

python中,定義一個類,和在PHP中定義一個類同樣,都是採用 class 關鍵字,可是其定義方式確實有些特殊,看下面的例子:spa

約定俗稱的,類的命名,咱們採用「駝峯法」而且首字母要大寫。設計

python 中 採用 class 關鍵字表示要定義一個類,後面的括號中表示這個類是從哪一個類繼承而來的,一般狀況下,要是你找不到一個合適的類繼承,那麼就繼承自最頂層的 object 吧,這卻是和 java 中有些類似。code

定義完類以後就是定義類的方法,也就是這個車有哪些功能。類的方法和函數定義沒有什麼區別,只是在類中,方法要求你必須設置一個 self 參數,並且該參數始終位於方法形參列表的第一個。固然了,形參要求你這麼來寫,可是在調用的時候你卻並不須要手動去傳遞這個參數。

python 類的實例化和其它編程語言有些不同,不須要使用 new  關鍵字,其它的沒有區別。

python 中調用類的方法及方法參數的傳遞,一樣和其它編程語言沒有區別。

3,訪問限制

如今,咱們來定義一個比較複雜一點的車類,就像是這樣:

如今這個類,它具備了車該有的功能和相應的屬性。一樣的,咱們經過類的對象或者叫作實例,在類的外面能夠訪問到類對應的屬性和其方法。

可是做爲一個類,應該具有最基本的封裝性,對於屬性和一些敏感方法,不該該在類的外面能夠直接訪問,應該將其私有化。

Python  中並無提供像PHP中的關於訪問權限的關鍵字,例如 private,它經過在屬性或者方法名以前增長一個「雙下劃線」來標識,該屬性或者方法,在類的外部不可以被直接訪問,就像是這樣:

在之後的python編程中,你會碰到變量名前面帶有「單下劃線」的變量,那麼它的含義是表示該變量雖然能夠被外部直接訪問,可是最好不要那麼作。

固然,對於python中的私有屬性或者方法,難道只要帶了「雙下劃線」就必定不能夠在類的外部被訪問到嗎?

其實不是的,對於「私有」屬性或者方法,Python只是對它們進行了重命名,這樣你直接調用它的時候就會產生找不到的假象,但實際上你是能夠訪問到的,就像這樣:這也是Python重命名的通用規則,在「私有」變量名以前增長「_ClassName」

你看,是否是就訪問成功了呢?

實際上,python並不會阻止你在程序中作任何的壞事,相反它對你不做任何的限制,爲了就是讓全部的責任都讓程序員本身來承擔,有助於你編寫出嚴謹的程序代碼!(總以爲,其實也不那麼好 。。。。)

4,設置器與訪問器

若是你知道java中的「豆子」這個東西,那麼對於設置器和訪問器應該就不會陌生,由於這個東西,我頭一次據說就是在java中。

它的大概思想是,針對類中的每個私有的屬性,若是想要被類外部的對象可以訪問和修改,那麼就必須針對這個屬性產生兩個共有的方法,這樣對象就能夠調用這兩個方法來達到修改和訪問私有屬性的目的。

因爲,這種東西只是一種思想,而並不是編程語言的特殊實現,所以在python中也能夠輕鬆的模擬:

在這裏,咱們把「setColor」和「getColor」方法,分別稱做是 Car 類中 私有屬性 color 的設置器和訪問器。

固然了,安裝約定俗成的規定,對於屬性的設置器的命名規範是「set」加上它的屬性名,一樣的訪問器就是「get」加上屬性名。

其實,上面的案例已經達到了咱們想要的效果,那在java中,這就是實現好了。可是在python中卻還要再追求一點簡單,因而就出現了 「@property」這個東西。

先看一個案例:

這樣,對於「私有屬性 __color」,能夠定義其對應的能夠供外部對象調用的方法「color」,在這個「color 方法」上使用了 @property 裝飾器以後,這個方法就變成了屬性「color」的訪問器。若是你還想給屬性「color」加一個設置器,那麼就能夠採用圖上的方式。

當採用 @property 的方式實現了屬性的訪問器和設置器以後,本來的私有屬性,在外面就能夠自由的以屬性的方式訪問了!

5,繼承,構造方法,多態

通過上面知識的大概說明,對於python的面向對象編程,其實有了一個大概的影像。以一個類的方式,編寫一些簡單的功能,仍是可以實現的。

不過對於OOP而言,繼承,絕對是重中之重。因此,下面的案例就演示了 python 中的繼承:

python 中的繼承,是在定義類的時候在後面的「()」中指定的。

在開始的時候,就說過,在定義 Car 類的時候,若是沒有合適的繼承類那麼就繼承自 object 類,由於這個是 python 中全部對象的頂層類。

那如今,我本身定義的  Bicycle 類則是繼承自自定義的  Car 類,繼承的語法規則就是那樣。

代碼樁:python 中對於一個空函數,或者空的類,須要使用 pass 來佔位。不然會報錯!這個大概是爲了 python 中沒有「{}」而作的補充,固然了,這裏能夠叫作「代碼樁」也能夠叫作「佔位符」

在講多態以前,咱們先看一下怎麼樣使用python的構造方法:

python中的構造方法叫:__init__  好像挺貼切!

對於繼承,若是子類也有對應的構造方法,那麼就須要顯式的調用父類的構造方法,調用父類的構造方法採用的方式和java中卻是有些相像,所以都是用 super 函數實現:

#-*- coding:utf-8 -*-

class Car(object):
    __color = None
    
    def __init__(self, color):
        self.__color = color
        
    @property
    def color(self):
        return self.__color

class Bicycle(Car):
    __width = None
    
    def __init__(self, width, color):
        super(Bicycle, self).__init__(color)
        self.__width = width
        
    @property
    def width(self):
        return self.__width

b = Bicycle(12,"blue")
print b.color
print b.width

多態是OOP編程中的一種設計思想,它是以OOP的繼承特性爲基礎來實現的,這裏跟python的基本特性相關不大,並且要描述清楚,仍是有些代碼要寫,限於博文太長,仍是先跳過!

6,補充知識

這裏涉及到python中的幾個魔術方法:

__str__ : 設置類的對象信息


__getattr__ 或者 __getattribute__ :用來設置,當經過對象訪問不存在的屬性時,調用的方法

__call__ : 能夠把對象當作函數來直接調用。感受用處不大!

-----------------------------------------------下篇寫異常--------------------------------------------------

感受,仍是 eclipse+pydev這個開發環境好些,PyCharm,真心感受有些渣!

相關文章
相關標籤/搜索