1. 程式人生 > >Python進階---面向對象的程序設計思想(一)

Python進階---面向對象的程序設計思想(一)

anim 它的 代碼冗余 tell 汽水 處理流程 關系 apach 精準

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機制會將類的函數綁定到對象上,稱為對象的方法,或者叫綁定方法,綁定方法唯一綁定一個對象,同一個類的方法綁定到不同的對象上,屬於不同的方法,內存地址都不會一樣
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進階---面向對象的程序設計思想(一)