Python物件導向三大特性
Python是物件導向的語言,也支援物件導向程式設計的三大特性:封裝(隱藏)、繼承、多型。
一、封裝(隱藏):
隱藏物件的屬性和實現細節,只對外提供必要的方法。相當於將"細節封裝起來",只對外暴露“相關呼叫方法”。通過私有屬性、私有方法的方式實現封裝。Python追求簡潔的語法,沒有嚴格的語法級別的"訪問控制符",更多的是依靠程式設計師的自覺實現。
二、繼承:
如果一個新類繼承自一個設計好的類,就直接具備了已有類的特徵,就大大降低了工作難度,已有的類,我們稱為"父類或基類",新的類,我們稱為“子類或派生類”。
繼承可以讓子類具有父類的特性,提高了程式碼的重用性。
Python支援多重繼承,一個子類可以繼承多個父類,繼承的語法格式如下:
class 子類類名(父類1,父類2,…):
類體
如果在類定義中沒有指定父類,則預設父類是object類,也就是說object類是所有類的父類,因此所有類都有object類的屬性和方法,object類裡面定義了一些所有類共有的預設實現,比如__init()__,_new__()。
定義子類時,必須在其建構函式中呼叫父類的建構函式(此處只是邏輯上的必須,語法上沒有嚴格要求,但是一般要調),呼叫格式如下:
父類名.__init__(self,引數列表)
#測試繼承的基本使用
class Person:
def __init__(self,name,age): #屬性在構造器中
self.name=name
self.__age=age #私有屬性(子類可以呼叫,但是不能用,也就是說子類繼承了父類所有的屬性方法,但是父類私有的屬性方法子類不能用)
def say_age(self):
print("嘿嘿,不告訴你")
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age)#必須顯式的呼叫父類初始化方法,不然直譯器不會去呼叫
self.score=score
# Student——>Person——>object類
print(Student.mro())#檢視類的繼承層次結構
s=Student("張無忌","18","100")
s.say_age()
print(s.name)
# print(s.age) 父類的私有屬性,子類不能用
print(dir(s))
print(s._Person__age)#例項物件._類名__私有屬性 這樣才可以用(這說明Python中並沒有完全意義上的私有,需靠程式設計師的自覺性去維護)
如果在子類中需要父類的構造方法就需要顯式的呼叫父類的構造方法,或者重寫父類的構造方法。
如果子類不重寫 __init__,例項化子類時,會自動呼叫父類定義的 __init__
如果重寫了__init__ 時,例項化子類,就不會呼叫父類已經定義的 __init__
如果重寫了__init__ 時,要繼承父類的構造方法,可以使用 super 關鍵字
類成員的繼承和重寫:
1.成員繼承:子類繼承了父類除構造方法之外的所有成員。
2.方法重寫:子類可以重新定義父類中的方法,這樣就會覆蓋父類中的方法,也稱為重寫。
class Person:
def __init__(self,name,age):
self.name=name
self.__age=age
def say_age(self):
print("我的年齡是",self.__age)
def say_introduce(self):
print("我的名字是{}".format(self.name))
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age)
self.score=score
def say_introduce(self):
'''重寫了父類的方法'''
print("報告老師,我的名字是{}".format(self.name))
s=Student("張無忌",18,100)
s.say_age()
s.say_introduce()
#列印結果
我的年齡是 18
報告老師,我的名字是張無忌
通過類的方法mro()或者類的屬性_mro_可以輸出這個類的繼承層次結構。
通過類的方法dir()檢視物件屬性
class A:
pass
class B(A):
pass
class C(B):
pass
#mro()檢視類的繼承層次結構
print(C.mro()) #或者用 print(C.__mro__)
#dir()檢視物件屬性
a=A()
print(dir(a))
#結果如下:
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
重寫_str_方法:
用於返回一個對於“物件的描述”,對應於內建函式str()經常用於print()方法,幫助我們檢視物件的資訊。_str_()可以重寫。
class Person():
def __init__(self,name):
self.name=name
p=Person("張三丰")
print(p)
#列印結果如下: object類中__str__()的預設實現,列印類的資訊
<__main__.Person object at 0x03110D30>
_str_()重寫後
class Person():
def __init__(self,name):
self.name=name
def __str__(self):
return "名字是:{}".format(self.name)
p=Person("張三丰")
print(p)
#列印結果如下:
名字是:張三丰
關於多重繼承:
Python支援多重繼承,一個子類可以有多個“直接父類”,這樣就具備了多個父類的特點,但是由於這樣會把“類的整體層次”搞得很複雜,儘量避免使用。
#測試多重繼承
class A:
def aa(self):
print("aa")
class B:
def bb(self):
print("bb")
class C(A,[B]):
def cc(self):
print("cc")
c=C()
#列印結果:
c.aa()
c.bb()
c.cc()
mro()
Python支援多繼承,如果父類中有相同名字的方法,在子類沒有指定父類名時,直譯器將“從左向右”按順序搜尋。
MRO(Method Resolution Order):方法解析順序,我們可以通過mro()方法獲得“類的層次結構”,方法解析順序也是按照這個“類的層次結構”尋找到。
class A:
def aa(self):
print("aa")
def say(self):
print("say AAA!")
class B:
def bb(self):
print("bb")
def say(self):
print("say BBB!")
class C(A,B):
def cc(self):
print("cc")
c=C()
print(C.mro())
c.say() #直譯器尋找方法是"從左到右的順序"尋找,此時會執行A類中的say()
#列印結果
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
say AAA!
super()獲得父類定義
在子類中,如果想要獲得父類的方法時,我們可以通過super()來做,super()代表父類的定義,而不是父類物件。
#測試super()代表和父類有關,而不是父類物件!
class A:
def say(self):
print("A:",self)
class B(A):
def say(self):
# A.say(self) 也可呼叫
super().say() #()中沒有傳self說明呼叫的是類方法,()中傳self說明呼叫的是類的例項化方法
print("B:",self)
B().say()
三、多型:
多型(polymorphism)是指同一個方法呼叫,由於物件不同可能會產生不同的行為。
注意:
1.多型是方法的多型,屬性沒有多型
2.多型的存在有兩個必要條件:繼承、方法重寫
class Man:
def eat(self):
print("餓了,吃飯了!")
class Chinese(Man):
def eat(self):
print("中國人用筷子吃飯")
class English(Man):
def eat(self):
print("英國人用刀叉吃飯")
class Indian(Man):
def eat(self):
print("印度人用右手吃飯")
def manEat(m):
if isinstance(m,Man):
m.eat()
else:
print("不能吃飯")
manEat(Chinese())
manEat(English())
#執行結果
中國人用筷子吃飯
英國人用刀叉吃飯
相關文章
- 2.1.1 Python物件導向三大特性Python物件
- golang 物件導向特性Golang物件
- 物件導向有哪些特性物件
- Python——物件導向Python物件
- Python物件導向Python物件
- python 物件導向Python物件
- 08 ### 物件導向三大特性物件
- Java物件導向三大特性Java物件
- Python物件導向三大特性是什麼?Python學習教程!Python物件
- python-程式導向、物件導向、類Python物件
- python物件導向(一)Python物件
- python物件導向(下)Python物件
- python物件導向一Python物件
- Python物件導向(上)Python物件
- 物件導向 -- 三大特性之多型物件多型
- C++物件導向三大特性C++物件
- Python - 物件導向程式設計 - 三大特性之繼承Python物件程式設計繼承
- python物件導向思想(類與物件)Python物件
- 物件導向 -- 三大特性之封裝物件封裝
- 物件導向 -- 三大特性之繼承物件繼承
- python物件導向[基礎]Python物件
- Python 物件導向介紹Python物件
- Python物件導向知多少?Python物件
- python 初識物件導向Python物件
- Python 物件導向筆記Python物件筆記
- 物件導向-物件導向思想物件
- 【Python】5.物件導向的PythonPython物件
- 【python 物件導向】 python物件學習筆記《1》Python物件筆記
- python---核心知識12之物件導向三大特性補充Python物件
- C#物件導向三大特性總結C#物件
- Java物件導向04——三大特性之多型Java物件多型
- 11-物件導向-2-三大特性物件
- 設計模式(二):物件導向及其特性分析設計模式物件
- Python物件導向程式設計Python物件程式設計
- 草根學Python(九) 物件導向Python物件
- 2.1.0 Python初識物件導向Python物件
- python之成員(物件導向)Python物件
- 面向Python,物件導向(基礎)Python物件