14 - 封裝、單繼承📄目錄1 封裝1.1 隱藏屬性(或稱私有權限)/隱藏方法1.1.1 隱藏屬性1.1.2 隱藏方法1.2 私有屬性/方法1.2.1 私有屬性1.2.2 私有方法2 繼承2.1 語法2.2 單繼承2.3 繼承的傳遞(多重繼承)3 方法的重寫3.1 覆蓋父類方法3.2 對父類方法進行擴展3.2.1 父類名.方法名(self)3.2.2 super.()方法名()3.2.3 super(子類名, self).方法名()4 新式類寫法4.1 class A 經典類①4.2 class A() 經典類②4.3 class A(object) 新式類(推薦使用)導航連結:
❗❗面向對象的三大特性:封裝、繼承、多態
💡 封裝:指隱藏對象中一些不希望被外部所訪問到的屬性或者方法
將複雜的信息、流程給包起來,內部處理,讓使用者只需要通過簡單操作步驟就能實現
xxxxxxxxxx
class Person:
name = 'Antonio' # 類屬性
pe = Person()
print(pe.name)
Person.name = 'Victoria'
print(Person.name)
輸出結果:
xxxxxxxxxx
Antonio
Victoria
⚠️這是完全公開的,能夠被完整訪問⚠️
💡 只允許在類的內部使用,無法通過對象訪問
使用:在屬性名或者方法名前面加上兩個下劃線__
xxxxxxxxxx
class Person:
name = 'Antonio' # 類屬性
__age = 28 # 隱藏屬性
def intro(self): # 實例方法
print(f'{Person.name}的年齡是{Person.__age}') # 在實例方法中訪問類屬性和隱藏屬性
pe = Person()
print(pe.name)
# print(pe.age) # 報錯,屬性錯誤
# print(pe.__age) # 報錯,屬性錯誤
# 訪問隱藏屬性的方法
# 第一種
# 隱藏屬性實際上是將名字修改為:_類名__屬性名,因此可以據此訪問甚至修改
print(pe._Person__age)
pe._Person__age = 18
print(pe._Person__age)
# 第二種:在類的內部訪問(推薦使用)
pe.intro()
輸出結果:
xxxxxxxxxx
Antonio
28
18
Antonio的年齡是28
方法一:
xxxxxxxxxx
class Man:
def __play(self): # 隱藏方法
print('玩手機')
def funa(self): # 普通方法
print('普通方法')
ma = Man()
ma._Man__play() # 第一種訪問隱藏方法的方式
輸出結果:
xxxxxxxxxx
玩手機
方法二:
xxxxxxxxxx
class Man:
def __play(self): # 隱藏方法
print('玩手機')
def funa(self): # 普通方法
print('普通方法')
# Man.__play(self) # 第二種方式之一。在實例方法中調用隱藏方法,不推薦
self.__play() # 第二種方式之二
ma = Man()
ma.funa()
輸出結果:
xxxxxxxxxx
普通方法
玩手機
xxx:普通屬性/方法
在類中定義的,則類可以在任意地方使用
_xxx:單下劃線開頭,聲明私有屬性或方法
如果定義在類中,外部可以使用,子類也可以繼承
但是在另一個py文件通過from xxx import *導入的時候無法導入
一般是為了避免與Python關鍵字衝突而採用的方法
__xxx:雙下劃線開頭,隱藏屬性
如果定義在類中,無法在外部直接訪問,子類不會繼承,要訪問只能通過間接方式
另一個py文件中通過from xxx import *導入的時候也無法導入
這種命名一般是Python中的魔術方法/屬性,都有特殊含義或者功能,自己不要輕易定義
xxxxxxxxxx
class Person:
name = "Antonio"
__age = 18 # 隱藏屬性
_sex = 'male' # 私有屬性
pe = Person()
# 訪問私有屬性/方法:對象名._屬性名調用
print(pe._sex)
輸出結果:
xxxxxxxxxx
male
xxxxxxxxxx
class Makeup:
def _buy(self): # 私有方法
print('Buying')
girl = Makeup()
girl._buy()
輸出結果:
xxxxxxxxxx
Buying
xxxxxxxxxx
class 類名(父類名):
代碼塊
💡 繼承分為單繼承和多繼承
xxxxxxxxxx
class Person: # 父類
def eat(self):
print('rice')
def sleep(self):
print('bed')
class Girl(Person): # 定義Girl類作為Person類的子類
pass # 佔位符,類下面不寫任何東西,會自動跳過
girl = Girl()
girl.eat() # 調用父類屬性成功
class Boy(Person): None # 一個父類可以有多個子類
# 可以寫None,但是不建議
boy = Boy()
boy.sleep()
輸出結果:
xxxxxxxxxx
rice
bed
總結:子類可以繼承父類的屬性和方法(但如init等會除外),就算子類自己沒有,也可以使用父類的
💡 A/B/C C類(子類)繼承B類(父類),B類(子類)繼承A類(父類)
👉🏻 C類具有A類和B類的屬性和方法
⚠️ 注意「多重繼承」與「多繼承」的區別
xxxxxxxxxx
class Father:
def eat(self):
print('eating')
def sleep(self):
print('sleeping')
class Son(Father):
pass
class Grandson(Son):
pass
gson = Grandson()
gson.eat()
輸出結果:
xxxxxxxxxx
eating
❗ 繼承的傳遞性就是子類擁有父類以及父類的父類中的屬性和方法
重寫:在子類中定義與父類相同名稱的方法
xxxxxxxxxx
class Person: # 父類
def money(self):
print(f'我有{100000}可以繼承')
class Man(Person): # 子類
def money(self):
print(f'我有{50000}可以繼承,要自己再賺{50000}')
man = Man()
man.money() # 雖然繼承了父類,但子類也有自己的方法,所以父類的方法被覆蓋
輸出結果:
xxxxxxxxxx
我有50000可以繼承,要自己再賺50000
💡 繼承父類的方法時,子類也可以增加自己的功能
xxxxxxxxxx
class Person: # 父類
def money(self):
print(f'我有{100000}可以繼承')
class Man(Person): # 子類
def money(self):
Person.money(self) # 先保留父類的方法
print(f'我有{50000}可以繼承,要自己再賺{50000}')
man = Man()
man.money()
輸出結果:
xxxxxxxxxx
我有100000可以繼承
我有50000可以繼承,要自己再賺50000
super在Python裡面是一個特殊的類,super()是使用super類創建出來的對象,可以調用父類中的方法
💡 推薦使用這一種,是第三種的簡寫——懶人寫法
xxxxxxxxxx
class Person: # 父類
def money(self):
print(f'我有{100000}可以繼承')
def sleep(self):
print('我要睡覺了')
class Man(Person): # 子類
def money(self):
super().money() # 創建super()對象調用父類money()方法
Person.sleep(self) # 對比第一種方法
print(f'我有{50000}可以繼承,要自己再賺{50000}')
man = Man()
man.money()
輸出結果:
xxxxxxxxxx
我有100000可以繼承
我要睡覺了
我有50000可以繼承,要自己再賺50000
xxxxxxxxxx
class Person: # 父類
def money(self):
print(f'我有{100000}可以繼承')
def sleep(self):
print('我要睡覺了')
class Man(Person): # 子類
def money(self):
super(Man, self).money()
print(f'我有{50000}可以繼承,要自己再賺{50000}')
man = Man()
man.money()
輸出結果:
xxxxxxxxxx
我有100000可以繼承
我有50000可以繼承,要自己再賺50000
xxxxxxxxxx
class A: # 經典類:不由任意內置類型派生出的類
pass
xxxxxxxxxx
class Animal:
def walk(self):
print('It can walk.')
class Dog(Animal):
pass # 仍然是經典類,不是派生類,因為沒有不同於父類的屬性或方法
💡 有了不同於父類的東西,就成為「派生類」
xxxxxxxxxx
class Animal:
def walk(self):
print('It can walk.')
class Dog(Animal): # 建立了不同於父類的屬性/方法,就成為派生類
name = 'Ben'
def bite(self):
print('It can bite.')
繼承了object或者該類的子類都是新式類
在Python3中,如果一個類沒有繼承任何類,默認繼承object類
因此在Python3中,上述三者沒有區別,都是新式類
object —— 對象,Python為所有對象提供的基類(頂級父類),提供了一些內置的屬性和方法,可以使用dir()查看
xxxxxxxxxx
print(dir(object))
輸出結果:
xxxxxxxxxx
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
目的地 | 超連結 |
---|---|
首頁 | 返回主頁 |
Python學習 | Python學習 |
上一篇 | 13 - 面向對象基礎 |
下一篇 | 15 - 多繼承&多態 |