面向對象編程——Object Oriented Programming,簡稱OOP,是一種程序設計思想。OOP把對象作爲程序的基本單元,一個對象包含了數據和操作數據的函數。
基本概念
- 類(Class): 用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。
- 方法:類中定義的函數。
- 類變量:類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數體之外。類變量通常不作爲實例變量使用。
- 數據成員:類變量或者實例變量用於處理類及其實例對象的相關的數據。
- 方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱爲方法的重寫。
- 局部變量:定義在方法中的變量,只作用於當前實例的類。
- 實例變量:在類的聲明中,屬性是用變量來表示的,這種變量就稱爲實例變量,實例變量就是一個用 self 修飾的變量。
- 繼承:即一個派生類(derived class)繼承基類(base class)的字段和方法。繼承也允許把一個派生類的對象作爲一個基類對象對待。例如,有這樣一個設計:一個Dog類型的對象派生自Animal類,這是模擬"是一個(is-a)"關係(例圖,Dog是一個Animal)。
- 實例化:創建一個類的實例,類的具體對象。
- 對象:通過類定義的數據結構實例。對象包括兩個數據成員(類變量和實例變量)和方法。
三大特徵
-
封裝
“封裝”就是將抽象得到的數據和行爲(或功能)相結合,形成一個有機的整體(即類);封裝的目的是增強安全性和簡化編程,使用者不必瞭解具體的實現細節,而只是要通過外部接口,一特定的訪問權限來使用類的成員。 -
繼承
即一個派生類(derived class)繼承基類(base class)的字段和方法。繼承也允許把一個派生類的對象作爲一個基類對象對待。
例如:一個 Dog 類型的對象派生自 Animal 類,這是模擬"是一個(is-a)"關係(例圖,Dog 是一個 Animal )。 -
多態
它是指對不同類型的變量進行相同的操作,它會根據對象(或類)類型的不同而表現出不同的行爲。
推薦:繼承和多態
類和實例
- 定義類
在 Python 中,定義類是通過 class 關鍵字:
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
解釋
- class 後面緊接着是類名,即 Student,類名通常是大寫開頭的單詞,緊接着是(object),表示該類是從哪個類繼承下來的,通常,如果沒有合適的繼承類,就使用object 類,這是所有類最終都會繼承的類。
- __init__方法的第一個參數永遠是 self,表示創建的實例本身,因此,在__init__方法內部,就可以把各種屬性綁定到 self,因爲 self就指向創建的實例本身。
注意:特殊方法“init”前後分別有兩個下劃線!!!
- 訪問限制
- 在 Python 中,實例的變量名如果以__開頭,就變成了一個私有變量(private),只有內部可以訪問,外部不能訪問。
- _name,這樣的實例變量外部是可以訪問的,但是,按照約定俗成的規定,當你看到這樣的變量時,意思就是,“雖然我可以被訪問,但是,請把我視爲私有變量,不要隨意訪問”。
- 實例
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self, score):
if 0 <= score <= 100:
self.__score = score
else:
raise ValueError('bad score')
def get_grade(self):
if self.__score >= 90:
return 'A'
elif self.__score >= 60:
return 'B'
else:
return 'C'
bart = Student('Bart Simpson', 59)
print('bart.get_name() =', bart.get_name())
bart.set_score(60)
print('bart.get_score() =', bart.get_score())
print('DO NOT use bart._Student__name:', bart._Student__name)