本文來自於千鋒教育在阿里雲開發者社區學習中心上線課程《Python入門2020最新大課》,主講人姜偉。
面向對象的
面向對象與面向過程
- 面向過程:根據業務邏輯從上到下寫代碼。
- 面向對象:將變量與函數綁定到一起,分類進行封裝,每個程序只要負責分配給自己的分類,這樣能夠更快速的開發程序,減少了重複代碼。
面向過程編程易被初學者接受,其往往用一長段代碼來實現指定功能,開發過程的思路是將數據與函數按照執行的邏輯順序組織在一起,數據與函數分開考慮,面向過程基本是由函數組成的。
面向過程編程
面向過程編程的關注點在於怎麼做
- 把完成某一個需求的 所有步驟 從頭到尾 逐步實現
- 根據開發需求,將某些 功能獨立 的代碼 封裝 成一個又一個 函數
- 最後完成的代碼,就是順序地調用 不同的函數
特點:
- 注重步驟與過程,不注重職責分工
- 如果需求複雜,代碼會變得很複雜
- 開發複雜項目,沒有固定的套路,開發難度很大!
面向對象基本概念
面向對象編程(Object Oriented Programming,OOP,面向對象程序設計)和麵向過程編程,是兩種不同的編程方式。
面向對象編程的關注點在於誰來做
相比較函數,面向對象是更大的封裝,根據職責在 一個對象中封裝多個方法
- 在完成某一個需求前,⾸首先確定職責 — 要做的事情(方法)
- 根據 職責 確定不同的 對象,在對象內部封裝不同的方法(多個)
- 最後完成的代碼,就是順序地調用不同對象的相應⽅方法。
特點:
- 注重 對象和職責,不同的對象承擔不同的職責。
- 更加適合應對複雜的需求變化,是專門應對複雜項目開發,提供的固定套路。
- 需要在面向過程基礎上,再學習一些面向對象的語法。
類和對象
類和對象是面向對象編程的兩個核心概念。
類
類是對一群具有相同特徵或者行為 的事物的一個統稱,是抽象的。
- 特徵其實就是一個變量,在類里我們稱之為屬性。
- 行為其實就是一個函數,在類里我們稱之為方法。
- 類其實就是由 屬性 和 方法 組成的一個抽象概念。
類就相當於製造飛機時的圖紙,是一個模板。這個模板只規定了飛機的某些特徵(例如大小,顏色,型號等
等)和行為(例如起飛,降落,飛行等等),它並不是一個具體的飛機,而是對飛機的一個抽象概念。它出現的目的,是為了讓我們的創建飛機對象。
對象
對象是由類創建出來的一個具體存在,可以直接使用。由哪一個類創建出來的 對象,就擁有在哪一個類中定義的屬性和⽅方法。 對象 就相當於用圖紙製造的飛機。在開發中,應該先有類,在類里定義好屬性和行為,再根據類來創建對象。
類和對象的關係
- 類是模板,對象是根據類這個模板創建出來的,應該先有類,再有對象。
- 使用同一個類,能夠創建出很多對象。
- 類中定義了什麼屬性和方法,對象中就有什麼屬性和方法。
- 不同對象對應的屬性值也會不同。
例如:定義了一個狗類,這個狗類有以下屬性:
- 品種
- 顏色
- 性別
- 名字
現在根據這個類創建出了兩條狗,這兩條狗分別是 哈士奇、灰色、母、二哈 和中華田園犬、黃色、公、旺財。我們發現,這兩條狗都具有 品種、顏色、性別和名字這些屬性,但是每條狗對應的屬性值卻不一樣。
類的設計
在使用面向對象開發前,應該首先分析需求,確定一下,程序中需要包含哪些類!
在程序開發中,要設計一個類,通常需要滿足一下三個要素:
- 類名 這類事物的名字,按照大駝峰命名法(每個單詞的首字母大寫)起名。
- 屬性 這類事物具有什麼樣的特徵。
- 方法 這類事物具有什麼樣的行為。
定義類名
名詞提煉法:分析整個業務流程,出現的名詞,通常就是找到的類。
屬性和方法的確定
- 對對象的特徵描述,可以定義成屬性
- 對象具有的行為(動詞)可以定義成方法
練習
需求1:
- 小明今年18 歲,身高 1.75,每天早上跑完步,會去 吃東西
- 小美今年17 歲,身高 1.65,小美不不跑步,小美喜歡 吃東西
需求2:
- 一隻黃顏色的狗狗叫大黃
- 看見生人汪汪叫
- 看見家人搖尾巴
針對於上面的練習,我們需要抽象理解成一個類。接著來介紹面向對象的基本語法。
面向對象基本語法
在Python中,對象幾乎是無處不在的,我們可以使用dir
內置函數來查看這個對象里的方法。
定義簡單的類(只包含方法)
面向對象是更大的封裝,在一個類中封裝多個方法,這樣通過這個類創建出來的對象,就可以直接調用這些方法了!
定義類
在Python中要定義一個只包含方法的類,語法格式如下:
class 類名:
def 方法1(self,參數列表):
pass
def 方法2(self,參數列表):
pass
1、方法的定義格式和之前學習過的函數一樣
2、方法里的第一個參數必須是self,大家暫時先記住,稍後介紹 self。
3、類名要遵守大駝峰命名法,每一個單詞的首字母都要大寫。類名定義的2種方法:
class <類名>:
class <類名>(object):
創建實例對象
當一個類定義完成之後,要使用這個類來創建對象,語法格式如下:
對象變量名 = 類名()
面向對象代碼
以上面的練習需求1為例:
class Student(object): #關注這個類有哪些特徵和行為
#在 __init__ 方法裡,以參數的形式定義特徵,我們稱之為屬性
def __init__(self, name, age, height):
self.name = name
self.age = age
self.height = height
#行為定義為一個個函數
def run(self):
print('正在跑步')
def eat(self):
print('正在吃東西')
# 使用 Student 類創建了兩個實例對象 s1 s2
# s1和s2都有name,age,height屬性,同時都有run和eat方法
s1 = Student('小明', 18, 1.75) # Student() ==> 會自動調用 __init__ 方法
s2 = Student('小美', 17, 1.65)
# 根據業務邏輯,讓不同的對象執行不同的行為
s1.run()
s1.eat()
s2.eat()
執行結果:
需求
- 小貓愛吃魚,小貓要喝水
分析
- 定義一個貓類 Cat
- 定義兩個方法 eat 和 drink
- 按照需求 —— 不需要定義屬性
class Cat:
"""這是個貓類"""
def eat(self):
print("小貓在吃東西")
def drink(self):
print("小貓在喝水")
tom = Cat() # 創建了一個Cat對象
tom.eat()
tom.drink()
hello_kitty = Cat() # 又創建了一個新的Cat對象
hello_kitty.eat()
hello_kitty.drink()
執行結果:
self的使用
給對象添加屬性
python支持動態屬性,當一個對象創建好了以後,直接使用 對象.屬性名 = 屬性值
就可以很方便的給對象添加一個屬性。
tom = Cat()
tom.name = 'Tom' # 可以直接給 tom 對象添加一個 name 屬性
這種方法很方便,但是,不建議使用這種方式給對象添加屬性。
self的概念
哪個對象調用了方法,方法里的self
指的就是誰。 通過 self.屬性名
可以訪問到這個對象的屬性;通過 self.方法名()
可以調用這個對象的方法。
class Cat:
def eat(self):
print("%s愛吃魚" %self.name)
tom = Cat()
tom.name = 'Tom' # 給 tom 對象添加了一個name屬性
tom.eat() # Tom愛吃魚
lazy_cat = Cat()
lazy_cat.name = "大懶貓"
lazy_cat.eat() # 大懶貓愛吃魚
直接給對象添加屬性的缺點
上述代碼中,我們是先創建對象,然後再給對象添加 name
屬性,但是這樣做會有問題。
tom = Cat()
tom.eat()
tom.name = "Tom"
程序運行時會報錯:
AttributeError: 'Cat' object has no attribute 'name'
錯誤提示:'Cat'對象沒有 'name' 屬性
在日常開發中,不推薦在類的外部直接給對象添加屬性這種方式。對象應該具有哪些屬性,我們應該封裝在類的內部。