1. 程式人生 > >python學習之路day06

python學習之路day06

本節內容:   1、面向物件程式設計介紹 2、為什麼要用面向物件進行開發? 3、面向物件的特性:封裝、繼承、多型 4、類、方法

1、面向過程 VS 面向物件 

程式設計正規化

程式設計是 程式 員 用特定的語法+資料結構+演算法組成的程式碼來告訴計算機如何執行任務的過程 , 一個程式是程式設計師為了得到一個任務結果而編寫的一組指令的集合,正所謂條條大路通羅馬,實現一個任務的方式有很多種不同的方式, 對這些不同的程式設計方式的特點進行歸納總結得出來的程式設計方式類別,即為程式設計正規化。 不同的程式設計正規化本質上代表對各種型別的任務採取的不同的解決問題的思路, 大多數語言只支援一種程式設計正規化,當然也有些語言可以同時支援多種程式設計正規化。 兩種最重要的程式設計正規化分別是面向過程程式設計和麵向物件程式設計。

面向過程程式設計(Procedural Programming)
Procedural programming uses a list of instructions to tell the computer what to do step-by-step. 
面向過程程式設計依賴 - 你猜到了- procedures,一個procedure包含一組要被進行計算的步驟, 面向過程又被稱為top-down languages, 就是程式從上到下一步步執行,一步步從上到下,從頭到尾的解決問題 。基本設計思路就是程式一開始是要著手解決一個大的問題,然後把一個大問題分解成很多個小問題或子過程,這些子過程再執行的過程再繼續分解直到小問題足夠簡單到可以在一個小步驟範圍內解決。

舉個典型的面向過程的例子, 資料庫備份, 分三步,連線資料庫,備份資料庫,測試備份檔案可用性。

def db_conn():

     print ( "connecting db..." )   def  db_backup(dbname):      print ( "匯出資料庫..." ,dbname)      print (
"將備份檔案打包,移至相應目錄..." )   def  db_backup_test():      print ( "將備份檔案匯入測試庫,看匯入是否成功" )   def  main():      db_conn()      db_backup( 'my_db' )      db_backup_test()   if  __name__  = =  '__main__' :      main()

面向物件程式設計

OOP程式設計是利用“類”和“物件”來建立各種模型來實現對真實世界的描述,使用面向物件程式設計的原因一方面是因為它可以使程式的維護和擴充套件變得更簡單,並且可以大大提高程式開發效率 ,另外,基於面向物件的程式可以使它人更加容易理解你的程式碼邏輯,從而使團隊開發變得更從容。

面向物件的幾個核心特性如下

Class 類
一個類即是對一類擁有相同屬性的物件的抽象、藍圖、原型。在類中定義了這些物件的都具備的屬性(variables(data))、共同的方法

Object 物件 
一個物件即是一個類的例項化後例項,一個類必須經過例項化後方可在程式中呼叫,一個類可以例項化多個物件,每個物件亦可以有不同的屬性,就像人類是指所有人,每個人是指具體的物件,人與人之前有共性,亦有不同

Encapsulation 封裝
在類中對資料的賦值、內部呼叫對外部使用者是透明的,這使類變成了一個膠囊或容器,裡面包含著類的資料和方法

Inheritance 繼承
一個類可以派生出子類,在這個父類裡定義的屬性、方法自動被子類繼承

Polymorphism 多型
多型是面向物件的重要特性,簡單點說:“一個介面,多種實現”,指一個基類中派生出了不同的子類,且每個子類在繼承了同樣的方法名的同時又對父類的方法做了不同的實現,這就是同一種事物表現出的多種形態。
程式設計其實就是一個將具體世界進行抽象化的過程,多型就是抽象化的一種體現,把一系列具體事物的共同點抽象出來, 再通過這個抽象的事物, 與不同的具體事物進行對話。
對不同類的物件發出相同的訊息將會有不同的行為。比如,你的老闆讓所有員工在九點鐘開始工作, 他只要在九點鐘的時候說:“開始工作”即可,而不需要對銷售人員說:“開始銷售工作”,對技術人員說:“開始技術工作”, 因為“員工”是一個抽象的事物, 只要是員工就可以開始工作,他知道這一點就行了。至於每個員工,當然會各司其職,做各自的工作。
多型允許將子類的物件當作父類的物件使用,某父型別的引用指向其子型別的物件,呼叫的方法是該子型別的方法。這裡引用和呼叫方法的程式碼編譯前就已經決定了,而引用所指向的物件可以在執行期間動態繫結

面向物件程式設計(Object-Oriented Programming )介紹

對於程式語言的初學者來講,OOP不是一個很容易理解的程式設計方式,大家雖然都按老師講的都知道OOP的三大特性是繼承、封裝、多型,並且大家也都知道了如何定義類、方法等面向物件的常用語法,但是一到真正寫程式的時候,還是很多人喜歡用函數語言程式設計來寫程式碼,特別是初學者,很容易陷入一個窘境就是“我知道面向物件,我也會寫類,但我依然沒發現在使用了面向物件後,對我們的程式開發效率或其它方面帶來什麼好處,因為我使用函式程式設計就可以減少重複程式碼並做到程式可擴充套件了,為啥子還用面向物件?”。 對於此,我個人覺得原因應該還是因為你沒有充分了解到面向物件能帶來的好處,今天我就寫一篇關於面向物件的入門文章,希望能幫大家更好的理解和使用面向物件程式設計。     無論用什麼形式來程式設計,我們都要明確記住以下原則:
  1. 寫重複程式碼是非常不好的低階行為
  2. 你寫的程式碼需要經常變更 
  開發正規的程式跟那種寫個執行一次就扔了的小指令碼一個很大不同就是,你的程式碼總是需要不斷的更改,不是修改bug就是新增新功能等,所以為了日後方便程式的修改及擴充套件,你寫的程式碼一定要遵循易讀、易改的原則(專業資料叫可讀性好、易擴充套件)。   如果你把一段同樣的程式碼複製、貼上到了程式的多個地方以實現在程式的各個地方呼叫 這個功能,那日後你再對這個功能進行修改時,就需要把程式裡多個地方都改一遍,這種寫程式的方式是有問題的,因為如果你不小心漏掉了一個地方沒改,那可能會導致整個程式的執行都 出問題。 因此我們知道 在開發中一定要努力避免寫重複的程式碼,否則就相當於給自己再挖坑。   還好,函式的出現就能幫我們輕鬆的解決重複程式碼的問題,對於需要重複呼叫的功能,只需要把它寫成一個函式,然後在程式的各個地方直接呼叫這個函式名就好了,並且當需要修改這個功能時,只需改函式程式碼,然後整個程式就都更新了。   其實OOP程式設計的主要作用也是使你的程式碼修改和擴充套件變的更容易,那麼小白要問了,既然函式都能實現這個需求了,還要OOP幹毛線用呢? 呵呵,說這話就像,古時候,人們打仗殺人都用刀,後來出來了槍,它的主要功能跟刀一樣,也是殺人,然後小白就問,既然刀能殺人了,那還要槍幹毛線,哈哈,顯而易見,因為槍能更好更快更容易的殺人。函式程式設計與OOP的主要區別就是OOP可以使程式更加容易擴充套件和易更改。 opp程式設計程式碼
class role(object):
def __init__(self,name,role,weapon,life_value=100,money=15000):
self.name=name
self.role=role
self.weapon=weapon
self.life_value=life_value
self.money=money
def shot(self):
print("shooting...")
def got_shot(self,name):
print("ah,%s....,I got shot..."%name)
def buy_gun(self,gun_name):
print("just bought %s"%gun_name)

r1=role("Alex","police","AK47")
r2=role("Jack","terrorist","B22")
r1.got_shot("ALex")
例項變數與類變數(私有方法)
class role(object):
def __init__(self,name,role,weapon,life_value=100,money=15000):
self.name=name
self.role=role
self.weapon=weapon
self.__life_value=life_value
self.money=money
def shot(self):
print("shooting...")
def __del__(self):
print("%s 徹底死了。。。。"%self.name)
def show_status(self):
print("name:%s,weapon:%s,life_value:%s"%(self.name,self.weapon,self.life_value))
def got_shot(self,name):
self.life_value-=50
print("ah,%s....,I got shot..."%name)
def buy_gun(self,gun_name):
print("just bought %s"%gun_name)

r1=role("Alex","police","AK47")
r2=role("Jack","terrorist","B22")
r1.got_shot("ALex")
r1.show_status()
r2.show_status()
r1.__life_value() #私有屬性不能單獨找到
繼承的程式碼

面向物件程式設計 (OOP) 語言的一個主要功能就是“繼承”。繼承是指這樣一種能力:它可以使用現有類的所有功能,並在無需重新編寫原來的類的情況下對這些功能進行擴充套件。

 
   

通過繼承建立的新類稱為“子類”或“派生類”。

 
   

被繼承的類稱為“基類”、“父類”或“超類”。

 
   

繼承的過程,就是從一般到特殊的過程。

 
   

要實現繼承,可以通過“繼承”(Inheritance)和“組合”(Composition)來實現。

 
   

在某些 OOP 語言中,一個子類可以繼承多個基類。但是一般情況下,一個子類只能有一個基類,要實現多重繼承,可以通過多級繼承來實現。

 
   

繼承概念的實現方式主要有2類:實現繼承、介面繼承。

 
    
    
     Ø         實現繼承是指使用基類的屬性和方法而無需額外編碼的能力;
     
    
   
 
   
    Ø         介面繼承是指僅使用屬性和方法的名稱、但是子類必須提供實現的能力(子類重構爹類方法);
    
   
 
    
    
     在考慮使用繼承時,有一點需要注意,那就是兩個類之間的關係應該是“屬於”關係。例如,Employee 是一個人,Manager 也是一個人,因此這兩個類都可以繼承 Person 類。但是 Leg 類卻不能繼承 Person 類,因為腿並不是一個人。
     
    
   
 
   
    抽象類僅定義將由子類建立的一般屬性和方法。
    
   
 
   

OO開發正規化大致為:劃分物件→抽象類→將類組織成為層次化結構(繼承和合成) →用類與例項進行設計和實現幾個階段。

class people():
def __init__(self,name,age):
self.Name=name
self.Age=age

def eat(self):
print("%s is eating..."%self.Name)
def talk(self):
print("%s is talking..." % self.Name)
def sleep(self):
print("%s is sleeping..." % self.Name)
class Man(people):
def piao(self):
print("%s go to dongguan..."%self.Name)
def sleep(self):
print("man is sleeping...")
class Woman(people):
def get_brith(self):
print("%s is borning a baby..."%self.Name)

m1=Man("chenronghua",25)
m1.eat()
w1=Woman("niuhanyang",26)
w1.get_brith()

多繼承(程式碼)

 

多型

多型性(polymorphisn)是允許你將父物件設定成為和一個或更多的他的子物件相等的技術,賦值之後,父物件就可以根據當前賦值給它的子物件的特性以不同的方式運作。簡單的說,就是一句話:允許將子類型別的指標賦值給父類型別的指標。 那麼,多型的作用是什麼呢?我們知道,封裝可以隱藏實現細節,使得程式碼模組化;繼承可以擴充套件已存在的程式碼模組(類);它們的目的都是為了——程式碼重用。而多型則是為了實現另一個目的——介面重用!多型的作用,就是為了類在繼承和派生的時候,保證使用“家譜”中任一類的例項的某一屬性時的正確呼叫。 Pyhon 很多語法都是支援多型的,比如 len(),sorted(), 你給len傳字串就返回字串的長度,傳列表就返回列表長度。

本節作業: 選課系統

角色:學校、學員、課程、講師
要求:
1. 建立北京、上海 2 所學校
2. 建立linux , python , go 3個課程 , linux\py 在北京開, go 在上海開
3. 課程包含,週期,價格,通過學校建立課程 
4. 通過學校建立班級, 班級關聯課程、講師
5. 建立學員時,選擇學校,關聯班級
5. 建立講師角色時要關聯學校, 
6. 提供兩個角色介面
6.1 學員檢視, 可以註冊, 交學費, 選擇班級,
6.2 講師檢視, 講師可管理自己的班級, 上課時選擇班級, 檢視班級學員列表 , 修改所管理的學員的成績 
6.3 管理檢視,建立講師, 建立班級,建立課程

7. 上面的操作產生的資料都通過pickle序列化儲存到檔案裡