標籤:字元 思維 空間 object 英雄聯盟 tin 變化 __init__ sata
thon的物件導向
一、面向過程與物件導向的對比
面向過程的程式設計的核心是過程(流水線式思維),過程即解決問題的步驟,面向過程的設計就好比精心設計好一條流水線,考慮周全什麼時候處理什麼東西。
優點是:極大的降低了程式的複雜度
缺點是:一套流水線或者流程就是用來解決一個問題,生產汽水的流水線無法生產汽車,即便是能,也得是大改,改一個組件,牽一髮而動全身。
應用情境:一旦完成基本很少改變的情境,著名的例子有Linux內核,git,以及Apache HTTP Server等。
物件導向的程式設計的核心是對象,Python中 一切皆對象,上帝思維,在上帝眼中這世間的一切都是對象,沒有的東西也能創造出來。
優點是:解決了程式的擴充性。對某一個對象單獨修改,會立刻反映到整個體系中,如對遊戲中一個人物參數的特徵和技能修改都很容易。
缺點:可控性差,無法向面向過程的程式設計流水線式的可以很精準的預測問題的處理流程與結果,物件導向的程式一旦開始就由對象之間的互動解決問題,即便是上帝也無法預測最終結果。於是我們經常看到一個遊戲人某一參數的修改極有可能導致某個遊戲的角色出現資料異常的技能,比如一刀砍死3個人,這樣就會很影響遊戲的平衡。
應用情境:需求經常變化的軟體,一般需求的變化都集中在使用者層,互連網應用,企業內部軟體,遊戲等都是物件導向的程式設計大顯身手的好地方。
二、類與對象
基於物件導向設計一個款遊戲:英雄聯盟,每個玩家選一個英雄,每個英雄都有自己的特徵和和技能,特徵即資料屬性,技能即方法屬性,特徵與技能的結合體就一個對象。
從一組對象中提取相似的部分就是類,類所有對象都具有的特徵和技能的結合體
在python中,用變數表示特徵,用函數表示技能,因而類是變數與函數的結合體,對象是變數與方法(指向類的函數)的結合體。
1.類的定義
‘‘‘
class 類名:
類的文檔字串
類體
‘‘‘
class Student:#class語句與定義函數類似 定義類名
school = ‘oldboy‘ #變數 這個類的特徵(每個對象的共同特徵)
def __init__(self,name,age): #初始化函數(各個對象的所專屬的特徵)
#只用來初始化的,並且一定不能有傳回值,
self.name=name
self.age=age
def study(self): #函數 這個類的技能(每個對象的共有技能)
pass
2.類的兩種作用:執行個體化和屬性引用
2.1執行個體化:類名加括弧
class Oldboy: #定義oldboy類
teacher_tyle="python"
def __init__(self,name,age,sex):
if not isinstance(name,str):
raise TypeError
self.name=name
self.age=age
self.sex=sex
def teach(self):
print("teach python")
def talk(self):
print("talk english")
def eat(self):
print("is eating")
name1=Oldboy("egon","18","boy")#執行個體化,其實就是在執行__init__這個初始化函數將參數傳入函數,執行個體化之後的內容被稱為對象。
2.2屬性引用:類名加屬性
Oldboy.teacher_tyle#引用類的資料屬性,該屬性與所有的執行個體(對象)共用。
Oldboy.teach#引用類的函數屬性,該屬性與所有的對象共用。
2.3對象的只有一個作用:屬性引用
name1.name
對象/執行個體本身只有資料屬性,但是python的class機制會將類的函數綁定到對象上,稱為對象的方法,或者叫Binder 方法,Binder 方法唯一綁定一個對象,同一個類的方法綁定到不同的對象上,屬於不同的方法,記憶體位址都不會一樣
name1.eat
3.類的名稱空間與對象的名稱空間。
建立一個類就會建立一個類的名稱空間,用來儲存類中定義的所有名字,這些名字稱為類的屬性
而類有兩種屬性:資料屬性和函數屬性其中類的資料屬性是共用給所有對象的
建立一個對象/執行個體就會建立一個對象/執行個體的名稱空間,存放對象/執行個體的名字,稱為對象/執行個體的屬性。
name1.name會先從對象自己的名稱空間中找name,找不到就去類裡面找,類找不到就去它父類中找,還是找不到的話拋出異常報錯!
三、類的繼承與派生
繼承是一種建立新類的方式,在python中,建立的類可以繼承一個或多個父類,父類又可稱為基類或超類,建立的類稱為衍生類別或子類
class People:
pass
class Animal:
pass
class Student(People,Animal): #people稱為基類或父類
pass
print(Student.__bases__)
print(People.__bases__)
print(Animal.__bases__)
#在python3中,所有類預設繼承object,
#但凡是繼承了object類的子類,以及該子類的子類,都稱為新式類(在python3中所有的類都是新式類)
#沒有繼承object類的子類成為經典類(在python2中,沒有繼承object的類,以及它的子類,都是經典類)
解決代碼重用的問題,減少代碼冗餘
繼承是一種什麼‘是’什麼的關係
class People:
def __init__(self, name, age):
# print(‘People.__init__‘)
self.name = name
self.age = age
def walk(self):
print(‘%s is walking‘ %self.name)
class Teacher(People):
pass
class Student(People):
pass
# t=Teacher(‘egon‘,18)
# print(t.name,t.age)
# print(t.__dict__)
# t.walk()
# s=Student(‘alex‘,13)
# print(s.name,s.age)
# s.walk()
四、組合
軟體重用的重要方式除了繼承之外還有另外一種方式,即:組合
組合指的是,在一個類中以另外一個類的對象作為資料屬性,稱為類的組合
組合:是一種什麼有什麼的關係,也是為了減少重複代碼
class People:
def __init__(self, name, age, year, mon, day):
self.name = name
self.age = age
self.birth = Date(year, mon, day)
def walk(self):
print(‘%s is walking‘ % self.name)
class Date:
def __init__(self,year,mon,day):
self.year=year
self.mon=mon
self.day=day
def tell_birth(self):
print(‘出生於<%s>年 <%s>月 <%s>日‘ % (self.year,self.mon,self.day))
class Teacher(People):
def __init__(self, name, age, year, mon, day,level,salary):
People.__init__(self,name,age,year,mon,day)
self.level=level
self.salary=salary
def teach(self):
print(‘%s is teaching‘ %self.name)
class Student(People):
def __init__(self, name, age, year, mon, day,group):
People.__init__(self,name,age,year,mon,day)
self.group=group
def study(self):
print(‘%s is studying‘ %self.name)
# t=Teacher(‘egon‘,18,1990,2,33)
# print(t.name,t.age)
# print(t.birth)
# t.birth.tell_birth()
# print(t.birth.year)
# print(t.birth.mon)
# print(t.birth.day)
五、介面
class File:#定義介面Interface類來模仿介面的概念,python中壓根就沒有interface關鍵字來定義一個介面。
# def read(self): #定介面函數read
# pass
#
# def write(self): #定義介面函數write
# pass
#
#
# class Txt(File): #文本,具體實現read和write
# def du(self):
# print(‘文本資料的讀取方法‘)
#
# def xie(self):
# print(‘文本資料的讀取方法‘)
#
# class Sata(File): #磁碟,具體實現read和write
# def read(self):
# print(‘硬碟資料的讀取方法‘)
#
# def write(self):
# print(‘硬碟資料的讀取方法‘)
#
# class Process(File):
# def read(self):
# print(‘進程資料的讀取方法‘)
#
# def write(self):
# print(‘進程資料的讀取方法‘)
#
#
# txt=Txt()
# disk=Sata()
# process=Process()
#
#
# txt.du()
# # disk.read()
# # process.read()
#
#
#父類要限制
#1;子類必須要有父類的方法
#2:子類實現的方法必須跟父類的方法的名字一樣
import abc
class File(metaclass=abc.ABCMeta):
@abc.abstractmethod
def read(self):
pass
@abc.abstractmethod
def write(self):
pass
class Txt(File): #文本,具體實現read和write
def read(self):
pass
def write(self):
pass
t=Txt()
Python進階---物件導向的程式設計思想(一)