溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Python 3 學(xué)習(xí)筆記:面向?qū)ο缶幊?/h1>
發(fā)布時間:2020-08-03 00:57:48 來源:網(wǎng)絡(luò) 閱讀:270 作者:wx5d52d9ece41bf 欄目:編程語言

概述

面向?qū)ο缶幊蹋∣bject Oriented Programming,即 OOP),是一種程序設(shè)計思想,比面向過程編程更加靈活,更易擴展。

Python 在設(shè)計的時候就是按照面向?qū)ο缶幊痰乃枷朐O(shè)計的,像我們前面學(xué)過的各種數(shù)據(jù)類型,如字符串、列表、字典等都是一個個對象,它們都具有各自的屬性和行為。

面向?qū)ο缶幊叹褪菍⒖陀^存在的事物,總結(jié)提煉出它們各自的屬性與行為,然后通過編程的方法形成一個模版(即類),我們就可以根據(jù)這個模版創(chuàng)建出一個個實際的、可使用的對象(即類的實例)。

特性

封裝

封裝是面向?qū)ο缶幊痰暮诵乃枷?,即將對象具有的,且是我們需要的屬性和行為封裝起來,編寫成一個模版(即類),而在使用的時候只需要事先根據(jù)定義好的模版創(chuàng)建出其實例即可,使用過程中無需知道其屬性和行為是如何實現(xiàn)的,只需要知道它們能夠完成哪些功能即可。

繼承

舉個例子,我們創(chuàng)建一個四邊形的類,它具有四條邊,四個角這兩個特性,計算周長、面積這兩個行為;當我們基于這個四邊形的類,再創(chuàng)建一個平行四邊形的類,則該平行四邊形也將自動具有四條邊、四個角的特性和計算周長、面積的行為。

繼承就是實現(xiàn)重復(fù)利用的重要手段,子類可以繼承父類的屬性和行為。

多態(tài)

子類繼承于父類,那么子類也就擁有了父類的特性和行為,但是因為子類相對于父類而言是一個全新的類,所以它也擁有自己獨特的特性和行為,這就是多態(tài)。例如,平行四邊形繼承于四邊形,同樣擁有四條邊和四個角同時,它也有自己的特性,如對邊相等,對角相等。

類和實例

面向?qū)ο缶幊痰乃枷刖褪怯么a描述客觀世界中的物體,但是不可能將每個物體都用代碼描述一遍,這不現(xiàn)實,所以引入了類。類就是一系列具有相同特性和行為的物體的集合,描述物體的模版。當我們需要一個該物體的具體實例時,只需要按照這個模版就能創(chuàng)建一個新的物體實例,然后對其進行操作。

如何定義類

在 Python 編程中,使用關(guān)鍵字 class 定義類,

class Triangle:
pass

Triangle(三角形)是類的名字。

創(chuàng)建類的實例

定義好一個類,并不能供我們直接使用,而是需要創(chuàng)建一個它的實例之后,才可以使用其內(nèi)部的屬性和行為。

就像國家發(fā)行鈔票,會制作的一個鈔票模版,然后根據(jù)這個模版印刷出一張張的紙幣,這些紙幣就是該鈔票模版的實例,市場上流通的也是這些紙幣,不會是這個鈔票模版。所以,當我們要使用這個類的時候,就需要將其實例化,創(chuàng)建一個它的實例,

class Triangle:
pass

if name == "main":
triangle = Triangle()

triangle 就是類 Triangle的實例,也是這個實例的名稱。

init() 方法

在 Python 中,如果在定義一個類的時候,不自定義該方法,則編譯器會自動幫我們指定一個。但是如果想在創(chuàng)建類的實例的時候,為它的屬性賦予一些參數(shù),就需要自定義一個 init() 方法。

該方法用于在創(chuàng)建類的實例時,傳入必要的屬性。它的第一個參數(shù)必須是 self ,代表實例本身,

class Triangle:
def init(self, base, height)
self.base = base
self.height = height

if name == "main":
triangle = Triangle(4, 5)

這樣就給 Triangle 這個類定義了一個 init() 方法,在創(chuàng)建其實例的時候,必須傳入除 self 以外的所有參數(shù)。

屬性

屬性指類中的變量,包括類的屬性和實例屬性,它們定義的位置不同。

類的屬性

類的屬性定義在類中(實例方法之外),所有類的實例都可以訪問類的屬性。

class Triangle:
triangle_amount = 0

def __init__(self, base, height):
    self.base = base
    self.height = height

    Triangle.triangle_amount += 1

if name == "main":
triangle_1 = Triangle(4, 5)
triangle_2 = Triangle(12, 5)

print(Triangle.triangle_amount)
print(triangle_1.triangle_amount)

類的屬性可以通過類名直接訪問,也可以通過類的實例訪問。

類的屬性不僅僅只能在定義類的時候定義,也可以在類的定義之外動態(tài)添加,

class Triangle:
triangle_amount = 0

def __init__(self, base, height):
    self.base = base
    self.height = height

    Triangle.triangle_amount += 1

if name == "main":
triangle_1 = Triangle(4, 5)
triangle_2 = Triangle(12, 5)

Triangle.triangle_number = "001"

print(triangle_1.triangle_number)
print(triangle_2.triangle_number)

實例屬性

實例屬性是指在類的方法中定義的屬性(變量),只能被類的實例使用。而且,改變一個實例的屬性并不會影響其他實例,

class Triangle:
def init(self, base, height):
self.base = base
self.height = height

def print_base(self):
    print(self.base)

def print_height(self):
    print(self.height)

if name == "main":
triangle_1 = Triangle(12, 5)
triangle_2 = Triangle(19, 7)

triangle_1.print_base()
triangle_1.print_height()

triangle_1.base = 20
triangle_1.height = 10

triangle_1.print_base()
triangle_1.print_height()

triangle_2.print_base()
triangle_2.print_height()

init() 方法中,base 和 height 就是實例屬性,當創(chuàng)建 triangle_1 和 triangle_2 兩個三角形的時候分別給它們的 base 和 height 屬性賦了值。當改變 triangle_1 的屬性后,并沒有影響 triangle_2 的屬性值。

方法

每個對象都有其獨有的行為,在面向?qū)ο缶幊讨邪堰@些行為稱為方法,也就是面向過程編程中的函數(shù),但是有些微差別。

方法需要在定義類的時候一起定義,這樣類的實例就可以使用這些方法。定義方法和定義函數(shù)相似,不過方法必須包含一個 self 參數(shù),且必須放在第一位,

class Triangle:
def init(self, base, height):
self.base = base
self.height = height

def compute_area(self)
    area = self.base * self.height / 2

函數(shù)用于實現(xiàn)某個獨立的功能,而實例方法是實現(xiàn)類(類的實例)的一個特性行為,只有類的實例可以使用它。

訪問限制

可以在類的外部訪問創(chuàng)建類的時候定義的屬性和方法,如果我們不想某些屬性或方法在類的外部被直接訪問(使用),可以給它們加上限制。不受限制的代碼如下:

class Triangle:
description = "我是這個類最原始的描述"

def __init__(self):
    pass

def print_base_height(self):
    print("我是這個三角形的底和高")

if name == "main":
print(Triangle.description)

triangle = Triangle()
triangle.print_base_height()

受保護的

以單下劃線開頭的屬性和方法是受保護的(protected)

class Triangle:
_description = "我是這個類最原始的描述"
_number = 0

def __init__(self):
    self._base = "我是底"
    print(self._base)

    pass

def _print_base_height(self):
    print("我是這個三角形的底和高")

if name == "main":
print(Triangle._description)

triangle = Triangle()
triangle._print_base_height()

print(triangle._base)

print(str(Triangle._number))
Triangle._number += 99
print(str(Triangle._number))

私有的

以雙下劃線開頭的屬性和方法是私有的(private),

class Triangle:
description = "我是這個類最原始的描述"
number = 0

def __init__(self):
    self.__base = "我是底"
    print(self.__base)

    pass

def __print_base_height(self):
    print("我是這個三角形的底和高")

def modify_description(self):
    print(Triangle.__description)

    Triangle.__description = "我是在類定義之內(nèi)修改的描述"
    print(Triangle.__description)

if name == "main":
triangle = Triangle()
triangle.modify_description()

print(triangle._Triangle__description)
triangle._Triangle__print_base_height()

print(str(triangle._Triangle__number))
triangle._Triangle__number += 99
print(str(triangle._Triangle__number))

通過上面的代碼可以看出,通過 類的實例名._類名__xxx 的方式依然可以訪問私有的屬性和方法。

所以,在 Python 編程中,訪問限制并不能真正的限制你,總是可以通過別的某種方法突破限制,全憑自覺吧。

@property

通過 @property(裝飾器)可以將一個方法轉(zhuǎn)換為一個用于計算的特殊屬性,可以通過方法名(無需在方法名后面加上小括號)直接訪問該方法,

class Triangle:
def init(self, base, height):
self.base = base
self.height = height

@property
def compute_area(self):
    return self.base * self.height / 2

if name == "main":
triangle = Triangle(12, 5)
print(triangle.compute_area)

繼承

繼承是面向?qū)ο缶幊痰囊粋€重要特性,被繼承的類稱為父類(或基類),繼承父類的類稱為子類(或派生類),子類具有父類除了私有屬性和方法以外的所有屬性和方法。繼承使得子類不再需要重新定義父類中已有的屬性和方法,只要拿過來直接用就可以了。

class Triangle:
def init(self, base, height):
self.base = base
self.height = height

@property
def compute_area(self):
    return self.base * self.height / 2

class IsoscelesTriangle(Triangle):
pass

if name == "main":
isosceless_triangle = IsoscelesTriangle(12, 5)
print(isosceless_triangle.compute_area)

多態(tài)

如果是僅僅只能繼承父類的一切,那和父類還有什么兩樣?所以,子類除了可以繼承父類,還可以根據(jù)自己的特點增加自己的特性,修改從父類集成的特性,也就是面向?qū)ο缶幊痰亩鄳B(tài)。

class Rectangle:
def init(self, length, width):
self.length = length
self.width = width

@property
def area(self):
    return self.length * self.width

@property
def perimeter(self):
    return (self.length + self.width) * 2

class Square(Rectangle):
def init(self, length, width=0):
self.length = length
self.width = width

@property
def area(self):
    return self.length ** 2

@property
def perimeter(self):
    return self.length * 4

if name == "main":
rectangle = Rectangle(12, 5)
print(str(rectangle.area))
print(str(rectangle.perimeter))

square = Square(12)
print(str(square.area))
print(str(square.perimeter))

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI