您好,登錄后才能下訂單哦!
概述
面向對象編程(Object Oriented Programming,即 OOP),是一種程序設計思想,比面向過程編程更加靈活,更易擴展。
Python 在設計的時候就是按照面向對象編程的思想設計的,像我們前面學過的各種數據類型,如字符串、列表、字典等都是一個個對象,它們都具有各自的屬性和行為。
面向對象編程就是將客觀存在的事物,總結提煉出它們各自的屬性與行為,然后通過編程的方法形成一個模版(即類),我們就可以根據這個模版創建出一個個實際的、可使用的對象(即類的實例)。
特性
封裝
封裝是面向對象編程的核心思想,即將對象具有的,且是我們需要的屬性和行為封裝起來,編寫成一個模版(即類),而在使用的時候只需要事先根據定義好的模版創建出其實例即可,使用過程中無需知道其屬性和行為是如何實現的,只需要知道它們能夠完成哪些功能即可。
繼承
舉個例子,我們創建一個四邊形的類,它具有四條邊,四個角這兩個特性,計算周長、面積這兩個行為;當我們基于這個四邊形的類,再創建一個平行四邊形的類,則該平行四邊形也將自動具有四條邊、四個角的特性和計算周長、面積的行為。
繼承就是實現重復利用的重要手段,子類可以繼承父類的屬性和行為。
多態
子類繼承于父類,那么子類也就擁有了父類的特性和行為,但是因為子類相對于父類而言是一個全新的類,所以它也擁有自己獨特的特性和行為,這就是多態。例如,平行四邊形繼承于四邊形,同樣擁有四條邊和四個角同時,它也有自己的特性,如對邊相等,對角相等。
類和實例
面向對象編程的思想就是用代碼描述客觀世界中的物體,但是不可能將每個物體都用代碼描述一遍,這不現實,所以引入了類。類就是一系列具有相同特性和行為的物體的集合,描述物體的模版。當我們需要一個該物體的具體實例時,只需要按照這個模版就能創建一個新的物體實例,然后對其進行操作。
如何定義類
在 Python 編程中,使用關鍵字 class 定義類,
class Triangle:
pass
Triangle(三角形)是類的名字。
創建類的實例
定義好一個類,并不能供我們直接使用,而是需要創建一個它的實例之后,才可以使用其內部的屬性和行為。
就像國家發行鈔票,會制作的一個鈔票模版,然后根據這個模版印刷出一張張的紙幣,這些紙幣就是該鈔票模版的實例,市場上流通的也是這些紙幣,不會是這個鈔票模版。所以,當我們要使用這個類的時候,就需要將其實例化,創建一個它的實例,
class Triangle:
pass
if name == "main":
triangle = Triangle()
triangle 就是類 Triangle的實例,也是這個實例的名稱。
init() 方法
在 Python 中,如果在定義一個類的時候,不自定義該方法,則編譯器會自動幫我們指定一個。但是如果想在創建類的實例的時候,為它的屬性賦予一些參數,就需要自定義一個 init() 方法。
該方法用于在創建類的實例時,傳入必要的屬性。它的第一個參數必須是 self ,代表實例本身,
class Triangle:
def init(self, base, height)
self.base = base
self.height = height
if name == "main":
triangle = Triangle(4, 5)
這樣就給 Triangle 這個類定義了一個 init() 方法,在創建其實例的時候,必須傳入除 self 以外的所有參數。
屬性
屬性指類中的變量,包括類的屬性和實例屬性,它們定義的位置不同。
類的屬性
類的屬性定義在類中(實例方法之外),所有類的實例都可以訪問類的屬性。
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)
類的屬性可以通過類名直接訪問,也可以通過類的實例訪問。
類的屬性不僅僅只能在定義類的時候定義,也可以在類的定義之外動態添加,
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 就是實例屬性,當創建 triangle_1 和 triangle_2 兩個三角形的時候分別給它們的 base 和 height 屬性賦了值。當改變 triangle_1 的屬性后,并沒有影響 triangle_2 的屬性值。
方法
每個對象都有其獨有的行為,在面向對象編程中把這些行為稱為方法,也就是面向過程編程中的函數,但是有些微差別。
方法需要在定義類的時候一起定義,這樣類的實例就可以使用這些方法。定義方法和定義函數相似,不過方法必須包含一個 self 參數,且必須放在第一位,
class Triangle:
def init(self, base, height):
self.base = base
self.height = height
def compute_area(self)
area = self.base * self.height / 2
函數用于實現某個獨立的功能,而實例方法是實現類(類的實例)的一個特性行為,只有類的實例可以使用它。
訪問限制
可以在類的外部訪問創建類的時候定義的屬性和方法,如果我們不想某些屬性或方法在類的外部被直接訪問(使用),可以給它們加上限制。不受限制的代碼如下:
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 = "我是在類定義之內修改的描述"
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(裝飾器)可以將一個方法轉換為一個用于計算的特殊屬性,可以通過方法名(無需在方法名后面加上小括號)直接訪問該方法,
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)
繼承
繼承是面向對象編程的一個重要特性,被繼承的類稱為父類(或基類),繼承父類的類稱為子類(或派生類),子類具有父類除了私有屬性和方法以外的所有屬性和方法。繼承使得子類不再需要重新定義父類中已有的屬性和方法,只要拿過來直接用就可以了。
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)
多態
如果是僅僅只能繼承父類的一切,那和父類還有什么兩樣?所以,子類除了可以繼承父類,還可以根據自己的特點增加自己的特性,修改從父類集成的特性,也就是面向對象編程的多態。
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))
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。