魔法函式
魔法函式名字是固定的,一般情況下我們不需要通過明顯的方式呼叫它們,但是它們會在特定階段自動執行,
__init__函式,它可以在實體化物件的時候修改屬性的值
class Rectangle:
length = 0
width = 0
def __init__(self, length, width):
self.length =length
self.width =width
def area(rect):
return rect.length *rect.width
def perimeter(rect):
return 2 * (rect.length+rect.width)
rect = Rectangle(3,4) # 當創建物件時,__init__函式被自動呼叫,3和4會創給length和width.
print(rect.length,rect.width)
print(rect.area())
魔法函式寫在類里面,所以init函式的至少有一個引數self,通過引數給要修改的屬性傳參,一般引數名往往和屬性名一致
一旦寫了__init__函式,并且__init__函式除了self以外還有其他引數,就需要為__init__函式除了self以外的引數傳入值,也可以給__init__函式的引數設定默認值,
__str__函式,該函式要求回傳一個字串,這個字串的資訊要能夠把物件的資訊組織起來,當我們使用print函式列印物件的時候,實際上列印的就是__str__函式回傳的字串,
class Rectangle:
length = 0
width = 0
def __init__(self,length=0,width=0):
self.length =length
self.width =width
def area(rect):
return rect.length *rect.width
def perimeter(rect):
return 2 * (rect.length +rect.width)
def __str__(self):
return '長方形的長是' + str(self.length) + ',寬是' + str(self.width)
rect =Rectangle(3, 4)
print(rect)
封裝
公有成員是可以公開使用的,即可以在類的內部進行訪問,也可以在外部程式中使用,Python中類的成員函式、成員變數默認都是公開的,
私有成員在類的外部不能直接訪問,一般在類的內部進行訪問和操作,或者在類的外部通過呼叫物件的公有成員方法來訪問,這是類的封裝特性的重要體現,
__xxx:以兩個下劃線開頭,表示類的私有成員,一般只有類物件自己能訪問,子類物件也不能直接訪問該成員,但可以通過“物件名._類名__xxx”這樣的特殊方式來訪問,
class Point:
x = 10
__y = 20
z = 30
def get_x(self):
return self.x
def get_y(self):
return self.__y
def __get_z(self):
return self.z
繼承
單繼承
面向物件的編程帶來的主要好處之一是代碼的重用,實作這種重用的方法之一是通過繼承機制,繼承用于指定一個類將從其父類獲取其大部分或全部功能,
它是面向物件編程的一個特征,這是一個非常強大的功能,方便用戶對現有類進行幾個或多個修改來創建一個新的類,新類稱為子類或派生類,從其繼承屬性的主類稱為基類或父類,
子類或派生類繼承父類的功能,向其添加新功能,它有助于代碼的可重用性,繼承的語法如下所示,
class 派生類(基類):
派生類類內陳述句
只需要繼承基類這個動作,就可以訪問到基類的屬性和方法了,它提高了代碼的可擴展性,
?如果派生類中有__init__()方法,那么基類的__init__()方法不會被自動呼叫,它需要在其派生類的構造中專門呼叫,
?如果派生類中沒有__init__()方法,且基類中有__init__()方法,那么基類的__init__()方法會被自動呼叫
?呼叫父類的方法有三種:
方法1:父類名字.父類中的方法名(self,[引數1,引數2,引數3,……])
方法2:super().父類中的方法名([引數1,引數2,引數3,……])
方法3:super(當前類的名字,self).父類中的方法名([引數1,引數2,引數3,……])
class Person(object):
def __init__(self,name,gender):
self.name =name
self.gender =gender
print("Person類__init__(),", "姓名:",self.name)
class Student(Person):
def __init__(self,name,gender,score):
super().__init__(name,gender)
self.score =score
print("Student類__init__(),", "姓名:",self.name)
student = Student('tom','male',10)
?Python總是首先查找對應型別的方法,如果它不能在派生類中找到對應的方法,它才開始到基類中逐個查找,
任何事情都有利有弊:繼承的一個弱點就是,可能特殊的類又有其他特殊的地方,又會定義一個類,其下也可能再定義類,這樣就會造成繼承的那條線越來越長,使用繼承的話,任何一點小的變化也需要重新定義一個類,很容易引起類的爆炸式增長,產生一大堆有著細微不同的子類,所以有個“多用組合少用繼承”的原則,
多重繼承
Python子類可以繼承一個基類,也可以繼承多個基類,這就是多重繼承,類的多重繼承的語法如下,
class 派生類(基類1,基類2,...):
派生類類內陳述句
在Python3.x版本其尋找方法遵循MRO原則,可以通過類.__mro__屬性輸出對應的方法尋找順序,
注意:__mro__屬性顯示指定類的所有繼承脈絡和繼承順序,假如這個指定的類不具有某些方法和屬性,
但與其有血統關系的類中具有這些屬性和方法,則在訪問這個類本身不具有的這些方法和屬性時,會按照__mro__顯示出來的順序一層一層向后查找,直到找到為止,
class P1:
def foo(self):
print("p1-foo")
class P2:
def foo(self):
print("p2-foo")
def bar(self):
print("p2-bar")
class C1(P1,P2):
pass
class C2(P1,P2):
def bar(self):
print("C2-bar")
class D(C1,C2):
pass
print(D.__mro__)
d=D()
d.foo()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/299041.html
標籤:其他
