python中面向对象的缺点_python中的面向对象和面向过程
一、面向?qū)ο蠛兔嫦蜻^程
一、什么是面向過程
核心是過程二字:面向過程是一種流水線的工作流程,是先做什么在做什么
二、什么是面向?qū)ο?/p>
核心 是對象二字:是一種編程思想,上帝思維,一切皆對象,編程中負責調(diào)度和控制
三、面向?qū)ο笈c面向過程的優(yōu)缺點
面向過程:
優(yōu)點:程序邏輯性強;復雜的問題簡單化
缺點:維護性差;功能拓展性差
面向?qū)ο?#xff1a;
優(yōu)點:功能拓展性強;維護性高,復用性強
缺點:代碼的復雜度提高了
四、如何創(chuàng)建類和對象
2.0 語法
class A:
def __init__(self,name,age):
self.name = naem
self.age = age
a1 = A() # 類型加括號在初始化階段自動觸發(fā)__init__() 方法創(chuàng)建一個空對象, 只有當傳值的時候才會再次觸發(fā)__init__()函數(shù)的方法,將對象進行初始化賦值 >>> 實列化產(chǎn)生對象的過程
2.1 如何設置屬性
類下的屬性是按照對象的需求進行創(chuàng)造的 ,對象需要什么叫設置什么屬性
2.2 屬性的查找順序
優(yōu)先找自己> 所在的類>父類
2.3 對象的初始化方法
2.4 綁定方法與非綁定方法
1.綁定給對象的方法,有在對象初始化的時候 2.類中函數(shù)的方法是默認綁定給對象用的會默認將實例化的對象傳過去當做函數(shù)的第一參數(shù),會用變量名 self 接收
2.當我們需要調(diào)用類使用函時加@classmethod 裝飾器下面的函數(shù)會自動將<類>作為第一參數(shù)傳過來 此時是默認綁定給類用的函數(shù)
3.@statimethod 靜態(tài)方法 不需要傳參數(shù)使用就綁定給誰
二、面向?qū)ο笕筇匦?/p>
一、繼承
二、封裝
三、多態(tài)
一、繼承
1、什是繼承
定義:描述的是什么 是什么的關系,在程序中描述的是類與類之間的關系,他們之間是存在一定關系的
super()方法
如果你繼承一個已有的類,并且你覆蓋了init 一定要先調(diào)用父類的init
子類訪問父類的屬性和方法:先找自己的>所在類>父類>object oject 是所有類的基類
2、為什用繼承:
原因:子類可以使用父類所有未被封裝的屬性和方法 ,提高代碼的重用性,不需要在子類中重寫__init__ 方法》》》實列化的初始賦值
3、繼承語法
a 繼承了b 那么b 就是a 的父類 a 就可以繼承父類b 的所有屬性和未被封裝的方法與數(shù)據(jù)屬性
4、先抽象在繼承
其實就是一個抽取相同屬性和共用方法的 過程,這個過程是抽象
classA:
name= 'alice'
def __init__(self, name, age):
self.name=name
self.age=ageclassB(A):passa1= A()
5、組合 什么沒有什么的關系
定義:把一個對象當做另一個對象的屬性 這兩不存在任何的關系 不是繼承
是為了使用它的屬性和功能
classDate:def __init__(self,year, month,day):
self.year=year
self.month=month
self.day=daydefinfo(self):print('我是date里的函數(shù)')classTeacher:def __init__(self,name, age, num,date):
self.name=name
self.age=age
self.num=num
self.date=datedefchange_score(self):print('修改分數(shù)')classStudent:def __init__(self,name,date):
self.date=date
self.name=namedefchoice(self):print('選擇')
d1= Date(2019,7,27)print(d1.year)print(d1.month)print(d1.day)#s1 = Student('koko') # koko想修改分數(shù) 或則拿到日期 沒辦法調(diào)
s2= Student('koko',d1)print(s2.date.year)print(s2.date.month)print(s2.date.day)
s2.date.info()#類內(nèi)函數(shù)直接執(zhí)行調(diào)用,不需要加括號打印,沒有返回值None 除非自己設置了return值
t1= Teacher('lire',18,10,d1)print(t1.date.year)
t1.date.info()
>>>>>
2019
7
27
2019
7
27
我是date里的函數(shù)
2019
我是date里的函數(shù)
6、派生
派是子類繼承父類方法和屬性時,自己有重新定義了新的屬性和方法
用的時候優(yōu)先使用自己的,自己沒有才會使用父類的
7、·覆蓋
子類在繼承父類時 自己有重新定義的屬性和方法 自己的屬性和方法和父類的名字一模一樣
9、新式類和經(jīng)典類
新式類:默認繼承object 類的叫新式類
python 中默認是新式類 沒有經(jīng)典類
經(jīng)典類:沒有繼承oject 類的叫經(jīng)典類 python2中是用的經(jīng)典類
10、菱形繼承mro :c3算法
類在查找=順序的時候會按照mro 的查找,深度優(yōu)先,如果在查找的過程中遇到幾個類同時繼承一個父類廣度優(yōu)先
二、封裝
2.1何為封裝
1.定義:將丑陋的復雜的,隱私的細節(jié)隱藏到內(nèi)部,對外部提供簡單的使用接口
對外隱藏內(nèi)部實現(xiàn),提供函數(shù)訪問的簡單的接口2.目的:1.為了保證數(shù)據(jù)的安全性2.對外隱藏實現(xiàn)細節(jié),隔離復雜度()主要原因就是隔離復雜度)3.什么時候用:1、當有一些數(shù)據(jù)不希望外界可以直接使用2.當有一些函數(shù)不希望給外界使用
4.語法:__屬性名在實列化賦初值
##### 被封裝的內(nèi)容的特點:
?1.外界不能直接訪問
?2.內(nèi)部依然可以使用 通過設定函數(shù)調(diào)用查詢##
2.3 封裝的語法
classPerson:
def __init__(self, name, age, id_number):
self.name=name
self.age=age
self.__id_number= id_number
2.4 封裝的原理:變量在類實列化對象進行初始值賦值的時候就已經(jīng)將我們隱藏的self._name 封裝成為_父類名__變量名 說以外部在沒有調(diào)用函數(shù)的基礎下,再次用對象點__name 是根本不可能訪問他的名字的
2.5 訪問私屬性的方法:裝飾器
classPerson:
def __init__(self, name, age, id_number):
self.name=name
self.age=age
self.__id_number=id_number
@property
def id_number(self):returnself.__id_number
p1= Person('coco', 18, 6666) # 類生成對象初識化 賦值 將產(chǎn)生的變量存放在名稱空間中 所以綁定關系在初始化的時候已經(jīng)確定了
# 封裝是將隱藏的屬進行封裝
方法:
1.如果想要訪問內(nèi)部已經(jīng)封裝的屬性一是可以在類的屬性下進行定義一個函數(shù) 在函數(shù) 內(nèi)返回 我們的要查找我們封裝好的變量名
def id_number(self):
returnself.__id_number
2. 加@property也是一樣的內(nèi)部代碼必須設計返回我們需要查找的數(shù)據(jù)屬性
為什么要使用@property
# 對于一寫封裝的屬性如何取值 和修改以及刪除classIphone:
def __init__(self,kind, price, red):
self.__kind=kind
self.__price=price
self.__red=red
# 方法red ,kind , price
@property
def red(self):returnself.__red
@red.setter
def red(self,new_color):
self.__red=new_color
IP= Iphone('蘋果', 4888, '紅色')
# print(IP.red()) # 函數(shù)可以直接訪問內(nèi)部封裝的東西
# print(IP.__red) # 現(xiàn)在沒有辦法獲取 怎么辦呢>>>可以@Property鴨 這樣就相當于IP.red 偽裝成對象點.red
print(IP.red)
IP.red= '綠色'# print(IP.red)
# print(IP.red)
# print(IP.red)
# print(IP.red)
print(IP.red) # 綠色 夾裝飾器是為了可以可以在外部修改和查看內(nèi)部的屬性和調(diào)用方法
原因是:設計是將函數(shù)名設計成和我們要所要訪問的變量名一模一樣>>>加@property后就可以直接對象點函數(shù)形
其實就是偽裝讓外部覺得他直接對象點變量名的拿到的變量名指向的內(nèi)存空間的值,實際情況是我們對外提供了接口,封裝了我們的在內(nèi)部實現(xiàn)細節(jié)。
如何訪問私有化的函數(shù):被封裝了的函數(shù)
#目的不讓外部修改內(nèi)部屬性和方法
classPerson:def __init__(self, name, age, id_number):
self.name=name
self.age=age
self.__id_number =id_number
@propertydefid_number(self):return self.__id_number
def __run(self): #如何訪問封值裝私有化的函數(shù) __run實質(zhì)變形為:_所屬的類名__函數(shù)名
print('running')print('密碼》》》009')def bar(self,y): #好簡單 在函數(shù)內(nèi)部在定義一個函數(shù) 他的返回結果就是封裝的函數(shù) 可以拿到里面的代碼執(zhí)行的內(nèi)容
if y < 100:return self.__run()
>>>>
好簡單 在函數(shù)內(nèi)部在定義一個函數(shù) 他的返回結果就是封裝的函數(shù) 可以拿到里面的代碼執(zhí)行的內(nèi)容
封裝原理:
__run實質(zhì)變形為:_所屬的類名__函數(shù)名
p1._Person__run() # 私有化原理
p1.bar(70) # 通過定義一個新的函數(shù)訪問 設置返回值
2.6.封裝計算屬性
#1.計算一個元或者一個長方形的面積
# 計算一個元或者一個長方形的面積classRadio:
def __init__(self,r=10):
self.__r=r
#計算周長
@property
def r(self):returnself.__r
@r.setter
def r(self, new_r):
self.__r=new_r
#計算面積
def ares(self):return 3.14*self.__r**2r1=Radio()
res1=r1.ares()
print(res1)
r1.r= 20# r2= Radio(20) # 內(nèi)部我們限定死了 所以沒有辦法更改 怎么辦
res=r1.ares()
print(res)
# 現(xiàn)在想把我的 可以通過外部進行改值
# print(r1.R())
# print(r2.R())
print(Radio.__dict__)
2. 計算BMI
#練習: 定義一個類叫做person#包含三個屬性 身高 體重 BMI#BMI的值需要通過計算得來 公式 體重 / 身高的平方
classBaseClass:def __init__(self, high, weight,):
self.high=high
self.weight=weightdefBMI(self):#公式:BMI = 體重(KG)/身高(m)的平方
return self.weight/self.high**2
#實列化對象
person1= BaseClass(1.65, 62)print(person1.BMI())"""當BMI指數(shù)為18.5~23.9時屬正常。
成人的BMI數(shù)值標準:
過輕:低于18.5 正常:18.5-23.9
過重:24-27 肥胖:28-32"""
2.7 鴨子類型
接口
何為接口:就是如USB接口提供一套統(tǒng)一標準的協(xié)議只要你遵循use制定的接口協(xié)議,你的設備盡可以通過使用usd 的功能 就可以連入電腦 進項相關操作
#接口:USB提供了一套統(tǒng)一的標準的也稱為協(xié)議,只要你遵循的這條套協(xié)議你的設備就可以連入電腦使用,不管你是 鼠標還是鍵盤都可以被識操作電腦
classMouse:defopen(self):print('鼠標打開電腦')defclose(self):print('鼠標關閉了')defread(self):print('鼠標獲取關光標')defwrite(self):print('鼠標不支持寫')defpc(usb_server):
usb_server.open()
usb_server.close()
usb_server.write()
usb_server.close()
m=Mouse()
pc(m)#這是外部函數(shù)加括號進行傳參
classKeyBord:defopen(self):print('鍵盤打開。。。')defclose(self):print('鍵盤關機了。。。')defread(self):print('獲取按鍵字符。。')defwrite(self):print('鍵盤寫入信息')#鴨子類型屬性也像都很像,方法有像 所以叫做鴨子類型
k=KeyBord()
pc(k)classUdisk:defopen(self):print('u盤啟動了')defclose(self):print('U盤關閉')defread(self):print('讀出數(shù)據(jù)')defwrite(self):print('寫入數(shù)據(jù)')
u=Udisk()
pc(u)
抽象 類
定義:abc 抽象類 就是函數(shù)體內(nèi)沒有函數(shù)體代碼 沒有任何函數(shù)體 定義函數(shù)功能 沒有函數(shù)內(nèi)容
# 強制要求子類的函數(shù)功能和父類功能一模一樣, 但是我們根據(jù)需求可以在子類函數(shù)體內(nèi) 定義添加功能其他功能代碼 抽象類就但是一套統(tǒng)一的接口 要用我的東西 可以 但必須遵循我的協(xié)議標準
#接口和抽像類:#何為接口:是一套協(xié)議規(guī)范,明確子類們應該具備哪些功能,#抽象類是用于強制要求字類必須按照協(xié)議中規(guī)定的來實現(xiàn),python 中不推崇
#鴨子類型:既可讓多個不同類對象具備相同屬性和方法對于使用者而言,就可以以不變應萬變,輕松的使用各種對象
"""abc
抽象類的定義:類中包含沒有函體的方法"""
importabcclass AClass(metaclass=abc.ABCMeta):
@abc.abstractmethoddefeat(self):pass@abc.abstractmethoddefeat1(self):pass
classGt(AClass):defeat(self):print('正在吃飯。。。。')defeat1(self):print('111111')whileTrue:
choice= input('調(diào)用此功能輸入指令:').strip()if choice == '123456':print('yes')break
else:print('false')continueb= Gt() #無法用抽象方法eat1 去實列化抽象類Gt
b.eat1()
鴨子類型
一個類看起來像鴨子(屬性),走起來也像(方法)就叫鴨子類型
然而,python 不推崇限制咱們的語法規(guī)則,我們可以設計成鴨子類型,即讓多個不同類對象具備相同的屬性和方法
對于使用者而言,就是可以以不變應萬變。輕松的是使用各種對象
三、多態(tài)
3.1 定義:多個不同的類可以響同一個方法,產(chǎn)生不同的結果
首先強調(diào)多態(tài)不是一種特殊的語法,而是一種狀態(tài),特征(多個不同的類可以響同一個方法,產(chǎn)生不同的結果)
即多個對象有不同的使用方法
3.2優(yōu)點:對于使用者而言大大的降低了使用難度
我們之前寫的USB接口下的使用難度(鴨子類型)多的屬于多態(tài)
3.3 接口,抽象類 都可以寫出具備多態(tài)的代碼,最簡單的就是鴨子類型
案列:
#實列 多態(tài)其實就是不同事物可以使用同一種方法,但是產(chǎn)生的結果會不同(觸發(fā)個方法的內(nèi)部執(zhí)行的內(nèi)容不同)
classChicken:#同一方法
defdown(self):print('雞下雞蛋。。。')classDuck:defdown(self):print('鴨下鴨蛋。。。')classGoose:defdown(self):print('鵝下鵝蛋。。。')
雞鴨鵝 都具有相同的功能,可以l利用實列化的對象 在內(nèi)部封裝一個調(diào)用接口
對象點自己內(nèi)部的函數(shù)加 括號 執(zhí)行對應的共能
#實列化對象
c =Chicken()
d=Duck()
g= Goose()
# 調(diào)用同一個方法
deffunc(obj):
obj.down()
func(c)
func(d)
func(g)
總結
以上是生活随笔為你收集整理的python中面向对象的缺点_python中的面向对象和面向过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【2023校招刷题】常见面试问题总结(一
- 下一篇: python神经网络预测的例子,神经网络