新開傳奇網(wǎng)站曾勁松線下推廣方式都有哪些
封裝、繼承、多態(tài)
當(dāng)談到封裝、繼承和多態(tài)時(shí),通常是在面向?qū)ο缶幊?(OOP) 的上下文中討論的。
封裝 (Encapsulation) 示例:
class Person: def __init__(self, name, age): self.__name = name # 使用雙下劃線前綴將屬性變?yōu)樗接?nbsp; self.__age = age
? def get_name(self): return self.__name
? def set_name(self, new_name): if len(new_name) > 0: self.__name = new_name
? def get_age(self): return self.__age
? def set_age(self, new_age): if new_age >= 0: self.__age = new_age
?
# 創(chuàng)建一個(gè)Person對象并訪問屬性
person = Person("Alice", 30)
print(person.get_name()) # 輸出:Alice
person.set_age(32) # 設(shè)置年齡
print(person.get_age()) # 輸出:32
在這個(gè)示例中,我們通過將屬性標(biāo)記為私有(使用雙下劃線前綴)來封裝數(shù)據(jù),并提供公共方法(get_name
、set_name
、get_age
、set_age
)來訪問和修改這些屬性。這樣,我們可以控制屬性的訪問和修改,以確保數(shù)據(jù)的安全性。
使用面向?qū)ο髞黹_發(fā),示例代碼如下:
- 類:理解為模板
- 對象:理解為實(shí)物
- 在使用面向過程編程時(shí),當(dāng)需要對數(shù)據(jù)處理時(shí),需要考慮用哪個(gè)模板中哪個(gè)函數(shù)來進(jìn)行操作,但是當(dāng)用面向?qū)ο缶幊虝r(shí),因?yàn)橐呀?jīng)將數(shù)據(jù)存儲(chǔ)到了這個(gè)獨(dú)立的空間中,這個(gè)獨(dú)立的空間(即對象)中通過一個(gè)特殊的變量(
__class__
)能夠獲取到類(模板),而且這個(gè)類中的方法是有一定數(shù)量的,與此類無關(guān)的將不會(huì)出現(xiàn)在本類中,因此需要對數(shù)據(jù)處理時(shí),可以很快速的定位到需要的方法是誰 這樣更方便 - 全局變量是只能有1份的,多個(gè)函數(shù)需要多個(gè)備份時(shí),往往需要利用其它的變量來進(jìn)行儲(chǔ)存;而通過封裝 會(huì)將用來存儲(chǔ)數(shù)據(jù)的這個(gè)變量 變?yōu)榱藢ο笾械囊粋€(gè)“全局”變量,只要對象不一樣那么這個(gè)變量就可以再有1份,所以這樣更方便
- 代碼劃分更清晰
繼承 (Inheritance) 示例:
class Animal: def __init__(self, name): self.name = name
? def speak(self): pass
?
class Dog(Animal): def speak(self): return f"{self.name} 說:汪汪汪!"
?
class Cat(Animal): def speak(self): return f"{self.name} 說:喵喵喵!"
?
# 創(chuàng)建一個(gè)Dog對象和一個(gè)Cat對象,并調(diào)用speak方法
dog = Dog("旺財(cái)")
cat = Cat("小花")
print(dog.speak()) # 輸出:旺財(cái) 說:汪汪汪!
print(cat.speak()) # 輸出:小花 說:喵喵喵!
在這個(gè)示例中,我們定義了一個(gè)基類 Animal
,然后創(chuàng)建了兩個(gè)派生類 Dog
和 Cat
,它們繼承了 Animal
的屬性和方法。每個(gè)派生類都可以覆蓋基類的方法(例如 speak
),以實(shí)現(xiàn)自己的行為。
- 能夠提升代碼的重用率,即開發(fā)一個(gè)類,可以在多個(gè)子功能中直接使用
- 繼承能夠有效的進(jìn)行代碼的管理,當(dāng)某個(gè)類有問題只要修改這個(gè)類就行,而其繼承這個(gè)類的子類往往不需要就修改
多態(tài) (Polymorphism) 示例:
class Shape: def area(self): pass
?
class Circle(Shape): def __init__(self, radius): self.radius = radius
? def area(self): return 3.14 * self.radius * self.radius
?
class Rectangle(Shape): def __init__(self, length, width): self.length = length self.width = width
? def area(self): return self.length * self.width
?
# 創(chuàng)建一個(gè)Shape的列表,包含不同類型的圖形對象
shapes = [Circle(5), Rectangle(4, 6), Circle(3)]
?
# 計(jì)算并輸出每個(gè)圖形的面積
for shape in shapes: print(f"面積:{shape.area()}")
在這個(gè)示例中,我們定義了一個(gè)基類 Shape
,以及兩個(gè)派生類 Circle
和 Rectangle
,它們都具有一個(gè)名為 area
的方法。通過多態(tài),我們可以在一個(gè)列表中存儲(chǔ)不同類型的圖形對象,然后通過統(tǒng)一的方法調(diào)用來計(jì)算它們的面積。這就是多態(tài)的核心思想,不同的對象可以對相同的方法做出不同的響應(yīng)。
class MiniOS(object):"""MiniOS 操作系統(tǒng)類 """def __init__(self, name):self.name = nameself.apps = [] # 安裝的應(yīng)用程序名稱列表def __str__(self):return "%s 安裝的軟件列表為 %s" % (self.name, str(self.apps))def install_app(self, app):# 判斷是否已經(jīng)安裝了軟件if app.name in self.apps:print("已經(jīng)安裝了 %s,無需再次安裝" % app.name)else:app.install()self.apps.append(app.name)class App(object):def __init__(self, name, version, desc):self.name = nameself.version = versionself.desc = descdef __str__(self):return "%s 的當(dāng)前版本是 %s - %s" % (self.name, self.version, self.desc)def install(self):print("將 %s [%s] 的執(zhí)行程序復(fù)制到程序目錄..." % (self.name, self.version))class PyCharm(App):passclass Chrome(App):def install(self):print("正在解壓縮安裝程序...")super().install()linux = MiniOS("Linux")
print(linux)pycharm = PyCharm("PyCharm", "1.0", "python 開發(fā)的 IDE 環(huán)境")
chrome = Chrome("Chrome", "2.0", "谷歌瀏覽器")
chrome2 = Chrome("Chrome2", "3.0", "古哥瀏覽器")linux.install_app(pycharm)
linux.install_app(chrome)
linux.install_app(chrome)
linux.install_app(chrome2)print(linux)Linux 安裝的軟件列表為 []
將 PyCharm [1.0] 的執(zhí)行程序復(fù)制到程序目錄...
正在解壓縮安裝程序...
將 Chrome [2.0] 的執(zhí)行程序復(fù)制到程序目錄...
已經(jīng)安裝了 Chrome,無需再次安裝
正在解壓縮安裝程序...
將 Chrome2 [3.0] 的執(zhí)行程序復(fù)制到程序目錄...
Linux 安裝的軟件列表為 ['PyCharm', 'Chrome', 'Chrome2']
多態(tài)需要用到繼承,重寫,調(diào)用某個(gè)方法時(shí),要看是父類創(chuàng)建的實(shí)例,還是子類創(chuàng)建的實(shí)例,實(shí)例不同調(diào)用的方法不同
關(guān)鍵點(diǎn):
- 定義了一個(gè)基類App,它具有name、version、desc屬性,以及一個(gè)install方法用于安裝。
- 定義了兩個(gè)子類PyCharm和Chrome,繼承自App。
- Chrome類對install方法進(jìn)行了重寫,添加了自定義的安裝邏輯。
- 在MainOS類中,通過install_app方法安裝不同的App實(shí)例對象,調(diào)用其install方法。
- 對于同一個(gè)install_app方法,傳入不同的類的實(shí)例,會(huì)調(diào)用各自類中不同的install實(shí)現(xiàn)。這就是多態(tài)。
- 多態(tài)允許我們基于同一接口編寫可擴(kuò)展和可維護(hù)的代碼。子類可以改變父類的行為,同時(shí)保持接口一致。
所以多態(tài)的關(guān)鍵是:
- 有繼承關(guān)系
- 子類覆蓋父類方法
- 對不同子類實(shí)例調(diào)用相同的方法
這使得調(diào)用者可以一致地調(diào)用方法,而具體執(zhí)行代碼依賴于運(yùn)行時(shí)對象的類型。這就是多態(tài)
-
面向過程開發(fā),簡單、開發(fā)前期快速,越往后越復(fù)雜,適合小工程
-
面向?qū)ο箝_發(fā),復(fù)雜、開發(fā)前期較慢,越往后開發(fā)越方便,適合大工程
沒有最好的開發(fā)模式,只有經(jīng)過多多練習(xí),見的多了,感受多了,自然也就能夠在不同的任務(wù)、不同的工程,使用合適的方式進(jìn)行開發(fā)
靜態(tài)方法和類方法
類屬性、實(shí)例屬性
它們在定義和使用中有所區(qū)別,而最本質(zhì)的區(qū)別是內(nèi)存中保存的位置不同,
-
實(shí)例屬性屬于對象
-
類屬性屬于類
class Province(object):# 類屬性country = 'china'def __init__(self, name):# 實(shí)例屬性self.name = name# 創(chuàng)建一個(gè)實(shí)例對象
obj = Province('shangdong')
# 直接訪問實(shí)例屬性
print(obj.name)
# 直接訪問類屬性
Province.country
由上述代碼可以看出【實(shí)例屬性需要通過對象來訪問】【類屬性通過類訪問】,在使用上可以看出實(shí)例屬性和類屬性的歸屬是不同的。
其在內(nèi)容的存儲(chǔ)方式類似如下圖:
由上圖看出:
-
類屬性在內(nèi)存中只保存一份
-
實(shí)例屬性在每個(gè)對象中都要保存一份
-
通過類創(chuàng)建實(shí)例對象時(shí),如果每個(gè)對象需要具有相同名字的屬性,那么就使用類屬性,用一份既可
實(shí)例方法、靜態(tài)方法和類方法
方法包括:實(shí)例方法、靜態(tài)方法和類方法,三種方法在內(nèi)存中都?xì)w屬于類,區(qū)別在于調(diào)用方式不同。
-
實(shí)例方法:由對象調(diào)用;至少一個(gè)self參數(shù);執(zhí)行實(shí)例方法時(shí),自動(dòng)將調(diào)用該方法的對象賦值給self;
-
類方法:由類調(diào)用; 至少一個(gè)cls參數(shù);執(zhí)行類方法時(shí),自動(dòng)將調(diào)用該方法的類賦值給cls;
-
靜態(tài)方法:由類調(diào)用;無默認(rèn)參數(shù);
class Foo(object):def __init__(self, name):self.name = namedef ord_func(self):""" 定義實(shí)例方法,至少有一個(gè)self參數(shù) """# print(self.name)print('實(shí)例方法')@classmethoddef class_func(cls):""" 定義類方法,至少有一個(gè)cls參數(shù) """print('類方法')@staticmethoddef static_func():""" 定義靜態(tài)方法 ,無默認(rèn)參數(shù)"""print('靜態(tài)方法')f = Foo("china")
# 調(diào)用實(shí)例方法
f.ord_func()
# 調(diào)用類方法
Foo.class_func()
# 調(diào)用靜態(tài)方法
Foo.static_func()
實(shí)例方法
類方法
靜態(tài)方法
- 相同點(diǎn):對于所有的方法而言,均屬于類,所以 在內(nèi)存中也只保存一份
- 不同點(diǎn):方法調(diào)用者不同、調(diào)用方法時(shí)自動(dòng)傳入的參數(shù)不同。
# 實(shí)例方法
# self參數(shù)表示當(dāng)前對象的實(shí)例
class Person:def __init__(self, name):self.name = namedef say_hello(self):print(f'Hello, my name is {self.name}')p = Person('John')
p.say_hello() # 調(diào)用實(shí)例方法,自動(dòng)傳遞當(dāng)前實(shí)例p作為self參數(shù)# 靜態(tài)方法
# 使用@staticmethod裝飾器聲明,不需要默認(rèn)的self參數(shù)
class Person:def __init__(self, name):self.name = name@staticmethoddef hello():print('Hello!')Person.hello() # 直接使用類名調(diào)用靜態(tài)方法,不需要實(shí)例化# 類方法
# 使用@classmethod裝飾器聲明,默認(rèn)參數(shù)cls代表當(dāng)前類本身
class Person:count = 0 # 類屬性def __init__(self, name):self.name =