Java的面向?qū)ο缶幊?/a>">Java的面向?qū)ο缶幊?/a>
711
2025-04-03
1.1,兩種思維方式
面向?qū)ο?/a>和面向過(guò)程是程序中兩種常見(jiàn)的思維方式。
1.1.1,面向過(guò)程
- 面向過(guò)程:把計(jì)算機(jī)程序視為一系列的命令集合,即一組函數(shù)的順序執(zhí)行。為了簡(jiǎn)化程序設(shè)計(jì),面向過(guò)程把函數(shù)繼續(xù)切分為子函數(shù),即把大塊函數(shù)通過(guò)切割成小塊函數(shù)來(lái)降低系統(tǒng)的復(fù)雜度。
- 優(yōu)點(diǎn):將復(fù)雜的問(wèn)題流程化,進(jìn)而簡(jiǎn)單化。
- 缺點(diǎn):擴(kuò)展性差。
1.1.2,面向?qū)ο蟾攀?/p>
- 面向過(guò)程:把計(jì)算機(jī)程序視為一系列的命令集合,即一組函數(shù)的順序執(zhí)行。為了簡(jiǎn)化程序設(shè)計(jì),面向過(guò)程把函數(shù)繼續(xù)切分為子函數(shù),即把大塊函數(shù)通過(guò)切割成小塊函數(shù)來(lái)降低系統(tǒng)的復(fù)雜度。
- Python中,所有數(shù)據(jù)類(lèi)型都可以視為對(duì)象,當(dāng)然也可以自定義對(duì)象。自定義的對(duì)象數(shù)據(jù)類(lèi)型就是面向?qū)ο笾械念?lèi)(Class)概念。
- 面向?qū)ο螅汉诵氖菍?duì)象二字,特征和技能的結(jié)合體。
- 優(yōu)點(diǎn):可拓展性高。
- 缺點(diǎn):編程復(fù)雜度高。
- 應(yīng)用場(chǎng)景:用戶需求經(jīng)常變化,互聯(lián)網(wǎng)應(yīng)用,游戲,企業(yè)內(nèi)應(yīng)用等。
1.1.3,把大象裝進(jìn)冰箱
2,類(lèi)和對(duì)象
- 類(lèi):類(lèi)作為設(shè)計(jì)藍(lán)圖來(lái)創(chuàng)建對(duì)象的代碼段,它描述了對(duì)象的特征,該對(duì)象具有什么樣的屬性,怎樣使用對(duì)象完成一些任務(wù),它對(duì)事件進(jìn)行怎樣的響應(yīng)等。
- 對(duì)象:對(duì)象是類(lèi)的一個(gè)實(shí)例,通常通過(guò)調(diào)用類(lèi)的一個(gè)構(gòu)造函數(shù)來(lái)創(chuàng)建它。
3,面向?qū)ο笾械男g(shù)語(yǔ)
- 封裝:封裝是一個(gè)概念,它的含義是把方法、屬性、事件集中到一個(gè)統(tǒng)一的類(lèi)中,并對(duì)使用者屏蔽其中的細(xì)節(jié)。
- 繼承:繼承是一種創(chuàng)建類(lèi)的方法,在現(xiàn)有類(lèi)(被繼承的類(lèi))基礎(chǔ)上,進(jìn)行拓展生成新的類(lèi),被稱(chēng)為子類(lèi)。被繼承的類(lèi)成為父類(lèi)、基類(lèi)、超類(lèi)。
- 多態(tài):一個(gè)同樣的函數(shù)對(duì)于不同的對(duì)象可以具有不同的實(shí)現(xiàn)。
4,Python中的面向?qū)ο?/p>
- Python是一門(mén)面向?qū)ο蟮木幊陶Z(yǔ)言,語(yǔ)言中內(nèi)建了面向?qū)ο蟮奶卣?。在Python中萬(wàn)物皆對(duì)象。
- Python支持多繼承。
- Python創(chuàng)建類(lèi)的方式如下:
class 類(lèi)名(父類(lèi)): ?# class關(guān)鍵字聲明類(lèi),父類(lèi)可以是多個(gè),默認(rèn)繼承object
'''類(lèi)說(shuō)明文檔'''
...類(lèi)體...
4.1,繼承(1)
- 編寫(xiě)了一個(gè)名為Animal的class,有一個(gè)run()方法可以直接打印:
class Animal(object): def run(self): print("Animal is running...")
- 當(dāng)我們需要編寫(xiě)Dog和Cat類(lèi)時(shí),就可以直接從Animal類(lèi)繼承:
class Dog(Animal): pass class Cat(Animal): pass dog=Dog() dog.run() # Animal is running... cat=Cat() cat.run() # Animal is running...
對(duì)于Dog來(lái)說(shuō),Animal就是它的父類(lèi),對(duì)于Animal而言,Dog就是它的子類(lèi),Cat和Dog類(lèi)似。
4.2,繼承(2)
- 繼承還可以一級(jí)一級(jí)地繼承下來(lái)
4.3,多態(tài)性:子類(lèi)中定義新方法
- 事實(shí)上,Python的多態(tài)性就體現(xiàn)在通過(guò)覆蓋父類(lèi)的方法來(lái)實(shí)現(xiàn),在運(yùn)行時(shí)根據(jù)傳遞的對(duì)象引用,來(lái)調(diào)用相應(yīng)的方法。Python默認(rèn)是多態(tài)的。
class Animal: def run(): raise AttributeError("子類(lèi)必須實(shí)現(xiàn)這個(gè)方法") class People(Animal): def run(self): print("人正在走") # 人正在走 class Dog(Animal): def run(self): print("狗在走") # 狗在走 class Cat(Animal): def run(self): print("貓?jiān)谧?) # 貓?jiān)谧?p=People() p.run() d=Dog() d.run() c=Cat() c.run()
4.4,私有化
- 默認(rèn)情況下,屬性在Python中都是"public",類(lèi)所在模塊和導(dǎo)入了類(lèi)所在模塊的其他模塊都可以訪問(wèn)到。如果類(lèi)中的某些屬性不想被外界訪問(wèn)或者繼承可以對(duì)其私有化。
- 模塊級(jí)的私有化:在屬性或方法前加上一個(gè)下劃線即可。防止模塊的屬性用"from mymodule import *"來(lái)加載,它只可以在本模塊中使用。
- 完全私有化:只能自己訪問(wèn)。在方法或?qū)傩郧凹与p下劃線。(Python中的完全私有化是一個(gè)假的私有化。它的作用其實(shí)是將之前的屬性或方法名改為了'_類(lèi)名._屬性/方法')。
4.5,Python對(duì)于封裝性的看法
- 設(shè)計(jì)封裝的邏輯往往要耗費(fèi)一定的精力,并且會(huì)導(dǎo)致代碼更加長(zhǎng)不易讀等等。
- Python的語(yǔ)言風(fēng)格沒(méi)有特別強(qiáng)調(diào)封裝性。它主張程序員自己通過(guò)更加嚴(yán)謹(jǐn)?shù)姆绞浇M織程序以避免出錯(cuò),而不是通過(guò)在語(yǔ)言層面實(shí)現(xiàn)封裝達(dá)到這一點(diǎn)。
- 但是,在Python中仍然可以實(shí)現(xiàn)對(duì)象的(非嚴(yán)格意義上的)封裝。
4.6,對(duì)象的封裝性(1)
- 例如在High_school_student類(lèi)中,雖然數(shù)據(jù)已經(jīng)被封裝在類(lèi)里面,但是我們還是可以通過(guò)外部訪問(wèn)其中的變量。我們可以在外部對(duì)age進(jìn)行修改。
class High_school_student(): def __init__(self): self.age=18.0 self.sex='M' student_a=High_school_student() print(student_a.age) # 18.0 student_a.age=28.0 print(student_a.age) # 28.0
4.7,對(duì)象的封裝性(2)
- 如果我們希望某些內(nèi)部屬性不被外部訪問(wèn),我們可以在屬性名稱(chēng)前加上兩個(gè)下劃線"__",表示將該屬性成員私有化,該成員在內(nèi)部可以被訪問(wèn),但是在外部是不能夠訪問(wèn)的。
class High_school_student(): def __init__(self): self.__age=18.0 self.__sex='M' student_a=High_school_student() print(student_a.__age) # AttributeError: 'High_school_student' object has no attribute '__age'
4.8,對(duì)象的封裝性(3)
- 成員私有化并不是代表完全不能夠從外部訪問(wèn)成員,而是提高了訪問(wèn)的門(mén)檻,防止意外或者隨意改變成員,引發(fā)錯(cuò)誤。我們?nèi)匀豢梢酝ㄟ^(guò)_類(lèi)名+私有變量,對(duì)變量進(jìn)行訪問(wèn)。
class High_school_student(): def __init__(self): self.__age=18.0 self.__sex='M' student_a=High_school_student() student_a.__age=18.8 print(student_a._High_school_student__age) # 18.0 print(student_a.__age) # 18.8
4.9,對(duì)象的封裝性(4)
- 成員私有化不僅包括屬性的私有化,也包括了方法的私有化,在方法名稱(chēng)前加上__(兩下劃線)也可以使得函數(shù)只能被內(nèi)部訪問(wèn),不能夠被外部訪問(wèn):
class High_school_student(): def __init__(self): self.age=18.0 self.sex='M' def __missing_detecting(self): if self.age=='': print("This is a missing value!") else: print("This is not a missing value!") student_a=High_school_student() student_a.__missing_detecting()
5.0,給對(duì)象添加不存在的屬性和方法
- 在Python中實(shí)例化對(duì)象以后,動(dòng)態(tài)的添加類(lèi)的屬性和方法同樣會(huì)影響對(duì)象。
- 動(dòng)態(tài)的屬性和方法也可以直接添加在對(duì)象上。添加在對(duì)象上不會(huì)反過(guò)來(lái)影響類(lèi)。
class Person(object): def __init__(self,age,name): self.age=age self.name=name p1=Person(18,'zhangsan') def eat(self): print("%s吃%s"%(self.name,self.food)) Person.food="雞蛋" Person.eat=eat p1.eat()
5.1,面向?qū)ο?函數(shù)與方法
- 函數(shù):函數(shù)是封裝了一些獨(dú)立的功能,可以直接調(diào)用,能將一些數(shù)據(jù)(參數(shù))傳遞進(jìn)去進(jìn)行處理,然后返回一些數(shù)據(jù)(返回值),也可以沒(méi)有返回值??梢灾苯釉谀K中進(jìn)行定義使用。
- 方法:方法和函數(shù)類(lèi)似,同樣封裝了獨(dú)立的功能,但是方法是只能依靠類(lèi)或者對(duì)象來(lái)調(diào)用的,表示針對(duì)性的操作。
- 區(qū)別:函數(shù)在Python中獨(dú)立存在,可直接使用的,而方法是必須被別人調(diào)用才能實(shí)現(xiàn)。靜態(tài)方法除外(與類(lèi)和對(duì)象無(wú)關(guān),通過(guò)類(lèi)名和對(duì)象名均可被調(diào)用,屬函數(shù))。
5.2,實(shí)例方法、靜態(tài)方法與類(lèi)方法
- 實(shí)例方法,第一個(gè)參數(shù)為self,調(diào)用時(shí)需要傳遞實(shí)例給self。
- 靜態(tài)方法,和類(lèi)有關(guān),但是在使用時(shí)并不需要類(lèi)或者實(shí)例本身(和函數(shù)類(lèi)似)。
通過(guò)@staticmethod實(shí)現(xiàn)
class C(): @staticmethod def f(): print("HuaweiCloud") C.f() # HuaweiCloud,靜態(tài)方法無(wú)需實(shí)例化 hw=C() hw.f() # HuaweiCloud,實(shí)例化后調(diào)用也可以
- 類(lèi)方法,第一個(gè)參數(shù)cls,調(diào)用時(shí)需要傳遞類(lèi)型給類(lèi)方法。對(duì)應(yīng)的函數(shù)不需要實(shí)例化,不需要self參數(shù),但第一個(gè)參數(shù)需要是表示自身類(lèi)的cls參數(shù),可以用來(lái)調(diào)用類(lèi)的屬性。
通過(guò)@classmethod實(shí)現(xiàn)
class A(): bar = 1 def func1(self): print("huawei") @classmethod def func2(cls): print("huawei-classmethod") print(cls.bar) cls().func1() A.func2() # 輸出結(jié)果 # huawei-classmethod # 1 # huawei
5,魔法方法
魔法方法是指Python內(nèi)部已經(jīng)包含的,被雙下劃線所包圍的方法(__init__),在面向?qū)ο蟮腜ython中,這些方法適用范圍廣泛,且功能強(qiáng)大。
5.1,常用魔法方法(1)
- __new__(cls[,...]):創(chuàng)建實(shí)例時(shí)首先調(diào)用的方法(構(gòu)造方法)。
- __init__(self[,...]):對(duì)象初始化方法(new方法返回對(duì)象后,調(diào)用init方法進(jìn)行屬性的初始化)。
new相較于init使用較少。
new可用于單例模式。
class Employee: def __new__(cls): print("__new__ magic method is called") inst=object.__new__(cls) return inst def __init__(self): print("__init__ magic method is called") self.name="Satya" emp=Employee() print(emp) # 輸出結(jié)果 # __new__ magic method is called # __init__ magic method is called
5.2,常用魔法方法(2)
- __del__(self):析構(gòu)方法,當(dāng)實(shí)例化對(duì)象被徹底銷(xiāo)毀時(shí)調(diào)用(實(shí)例化對(duì)象的所有指針都被銷(xiāo)毀時(shí)被調(diào)用)。
- __len__(self):定義當(dāng)被len()調(diào)用時(shí)的操作。
- len(obj)
- __bool__(self):定義當(dāng)被bool()調(diào)用時(shí)的行為,應(yīng)該返回True或者False。
l=[1,2,3,4] print(l.__len__()) # 4 r=1>2 print(r.__bool__()) # False
5.3,常用魔法方法(3)
- __str__(self):定義當(dāng)被str()調(diào)用時(shí)的操作。
默認(rèn)返回對(duì)象信息。
print對(duì)象時(shí)會(huì)被執(zhí)行。
str()用于將值轉(zhuǎn)化為適合人們閱讀的形式。
- __repr(self):定義當(dāng)被repr()調(diào)用時(shí)的行為。
repr()用于將值轉(zhuǎn)化為供解釋器讀取的形式。
class myclass: def __init__(self): self.name="Raj" self.age=21 def __str__(self): return "name : {} age : {}".format(self.name, self.age) def __repr__(self): return {"name":self.name, "age":self.age} obj = myclass() print(obj.__str__()) # name : Raj age : 21 print(obj.__repr__()) # {'name': 'Raj', 'age': 21}
5.4,常用魔法方法(4)
- __getattr__(self,name):定義當(dāng)用戶試圖獲取一個(gè)不存在的屬性時(shí)的行為。
- __setattr__(self,name,value):定義當(dāng)一個(gè)屬性被設(shè)置時(shí)的行為。
- __getattribute__(self,name):定義當(dāng)該類(lèi)的屬性被訪問(wèn)時(shí)的行為。
訪問(wèn)對(duì)象屬性或者方法時(shí),首先被調(diào)用的方法。
# getattr() class A(): a = 5 def __init__(self,x): self.x = x def hello(self): return "hello func" a = A(10) print(getattr(a,"x")) # a.x,10 print(getattr(a,"y",18)) # a.y,當(dāng)不存在時(shí)返回第三個(gè)參數(shù)作為默認(rèn)值,18 print(getattr(a,"hello")()) # a.hello(),hello func print(getattr(A,"a")) # A.a,5 # __getattr()__與__getattribute()__ class A(object): ''' 從輸出結(jié)果得知,在獲取對(duì)象屬性時(shí), __getattribute()__ 一定被調(diào)用,不管屬性存不存在, 首先都會(huì)調(diào)用。如果碰到 a.y 這種不存在對(duì)象時(shí), __getattribute()__ 會(huì)找不到,這時(shí)再 調(diào)用 __getattr()__ ,可以通過(guò)這個(gè)方法設(shè)置屬性不存在時(shí)的默認(rèn)值。 ''' def __init__(self,x): self.x=x def hello(self): return "hello func" def __getattr__(self,item): print("in __getattr__") return 100 def __getattribute__(self, item): print("in __getattribute__") return super(A,self).__getattribute__(item) a = A(10) print(a.x) print(a.y) # 輸出結(jié)果 # in __getattribute__ # 10 # in __getattribute__ # in __getattr__ # 100
5.5,Python類(lèi)中的內(nèi)置屬性
- __dict__:類(lèi)的屬性(包含一個(gè)字典,由類(lèi)的數(shù)據(jù)屬性組成)。
- __doc__:類(lèi)的文檔字符串。
- __name__:類(lèi)名。
- __module__:類(lèi)定義所在的模塊
類(lèi)的全名是'__main__.className',如果類(lèi)位于一個(gè)導(dǎo)入模塊mymod中,那么className.__module__等于mymod。
- __bases__:類(lèi)的所有父類(lèi)構(gòu)成元素(包含了一個(gè)由所有父類(lèi)組成的元組)。
# __dict__ class A: a = 1 b = 2 def __init__(self): self.s = "hello world" print(A.__dict__) # 輸出結(jié)果 # {'__module__': '__main__', 'a': 1, 'b': 2, # '__init__':
Python
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。