先來看一個類
class Student(object):
teacher = 'Alice' # 共有類屬性(常量),類和實例方法都可以訪問,訪問方法:類名.xxx
def __init__(self, age, name): # 魔法函數(shù),實例化對象時自動調(diào)用。實例屬性一般放在這里
self.age = age # 實例屬性,只有類可以訪問,訪問方法:self.xxx 或者 對象.xxx
self.name = name
self._score = 2000 # 淺度私有屬性,類和對象都可以訪問
self.__money = 4000 # 深度私有屬性,只有類內(nèi)部可以訪問
def info(self, name): # 這里都函數(shù)就是實例方法,或者叫實例對象
# 在方法內(nèi)部,可以通過self.屬性/方法 來調(diào)用或者修改對象的其它屬性或者方法。
# self.name = name # 實例屬性,但是一般放在init下面
pass
@classmethod # 裝飾器的語法糖,java叫注解
def course(cls): # 類方法(所有實例方法共有),cls代表當前類對象
pass
@staticmethod # 裝飾器的語法糖,java叫注解
def school(): # 靜態(tài)方法,可以沒有參數(shù)/self/cls
pass
# 可以通過這個方法得到深度私有屬性的值。
def get_money(self):
print(self.__money)
def __myself(self): # 私有方法
pass
# 通過類名來訪問類屬性
print(Student.teacher)
# 實例化對象=實例化類,創(chuàng)建對象。Student是類,stu是對象。根據(jù)init函數(shù)傳參
stu = Student('18', 'lili')
# 通過對象來訪問類屬性:對象名.屬性
print(stu.name)
# 通過對象來調(diào)用實例方法:對象名.方法()
stu.info()
# 通過對象來訪問淺度私有屬性
print(stu._score)
# 通過對象是不能訪問到深度私有屬性的,下面的print會報錯
# print(stu.__money)
# 可以通過上面定義的獲取深度私有屬性的函數(shù)來獲取深度私有屬性值
print(stu.get_money())
個人理解
- 屬性一般是指變量,也有定義常量屬性的
- 在定義類的時候,并不知道對象是誰。用self來表示對象。所以實例化對象是誰,self就代表誰。
- 類里面可以創(chuàng)建多個對象(即函數(shù)),每個對象都是獨立的,并且每個對象都擁有類里的所有方法。
- 類:抽象的,對象共有的特征。對象:具體的存在,有很多個。
==上面的Student是類,傳參數(shù)后實例賦給stu,stu就是類對象。
==定義一個def函數(shù),函數(shù)有方法/有參數(shù),這個函數(shù)是一個實例對象。
==python里面造對象:實例化 - 類名使用大駝峰命名;函數(shù)名需要小寫,可以使用小駝峰
- 實例屬性和類屬性的優(yōu)先級:對于對象(def函數(shù))來說,自己有就用自己的,自己沒有就要類的。都沒有會報錯
- 關(guān)于object:python3中,class A 默認類都會繼承object;python2中,class A(object),需要自己帶上object
名詞解釋(公有)
實例屬性
在def函數(shù)內(nèi)部定義的屬性
類屬性
類所有的屬性,定義在函數(shù)外面,類和實例都可以訪問
實例方法
實例方法就是def函數(shù),第一個參數(shù)是self。也叫實例對象
類方法
需要修飾器@classmethod,標示其為類方法,類方法的第一個參數(shù)必須為類對象,一般用cls表示,通過cls引用的必須是類屬性和類方法。
靜態(tài)方法
需要修飾器@staticmethod,標示其為靜態(tài)方法。需要做一些功能,和類相關(guān),但不需要類和對象參與,此時可以使用靜態(tài)方法,靜態(tài)方法可以不需要參數(shù)。
三種方法的區(qū)別
實例方法:用self,對象去調(diào)用
類方法:@classmethod 修飾,用cls。類和對象都可以調(diào)用,一般是類去調(diào)用
靜態(tài)方法:@staticmethod 修飾。沒有一定要傳self或者cls,類和對象都可以調(diào)用
魔法方法
def init(): 函數(shù)叫魔法方法,存放實例屬性(公共變量)。做初始化的動作,可以初始化函數(shù),實例化對象的時會自動調(diào)用
關(guān)于私有化
書寫格式
1,屬性名/方法名
淺度私有,約定俗成的。通過對象.屬性名/方法名實際是可以訪問的,但它的意思是:別訪問我,我是私有的。
2,屬性名/方法名
深度私有。通過對象.屬性名/方法名不能訪問,只有類內(nèi)部可以訪問。
3,_ 和 __ 私有化方式同樣在模塊(.py)當中也支持。模塊內(nèi)私有,僅想在模塊內(nèi)使用,其它模塊導的時候,表示這些不想被外部訪問。
什么情況下需要私有化
當模塊/類要實現(xiàn)一個大功能,而這個功能由很多個內(nèi)部的小功能(函數(shù)不應(yīng)該太復雜)組成的。但是這些小功能對于使用者而言不需要看見/不需要使用。我們就會做成私有化。
私有屬性
類外通過類對象引用不能直接更改,只能通過實例方法調(diào)用類對象更改。
私有方法
只能在類內(nèi)調(diào)用,如果類外調(diào)用,則需要類內(nèi)的公有方法調(diào)用類內(nèi)的私有方法,在類外調(diào)用這個公有方法,則間接調(diào)用了私有方法。
繼承
- 子類可以繼承父類
- 淺度私有屬性/方法可以繼承,深度私有屬性/類不可以繼承
- 子類繼承父類,擁有父類所有屬性和方法,除了深度私有化的以外。
- python多繼承:可以繼承多個父類。但是我們一般只繼承一個父類
- 繼承的語法:class 子類(父類1, 父類2...):
- 繼承后可以做的事
1,在父類的功能或者屬性以外,添加屬于你自己的方法/屬性。
2,子類重寫父類方法:在父類原有的基礎(chǔ)和功能上去優(yōu)化。
2.1,不動父類的共能,只增加一些新的功能
2.2,推翻父類的功能,重新寫一遍 - 在與父類同名的方法內(nèi),想調(diào)用父類的同名方法super(super叫做超類)
- 子類有的用自己的,子類沒有的用父類的
- 方法重栽:Java里面有,python里面沒有。(處理場景:參數(shù)個數(shù)不一樣,參數(shù)類型不一樣)
以下是關(guān)于繼承的簡單使用
class Father(object):
def __init__(self, name, age):
self.name = name
self.age = age
def earn_money(self, work):
print(f'{self.name}通過{work}來賺錢')
def hobby(self, hobby):
print(f'{self.name,}的愛好是:{hobby}')
class Son(Father): # 繼承父類Father
# 新增一個實例方法,在父類方法以外,只屬于自己的方法
def study(self, content):
print("我通過學習 {} 來提升自己".format(content))
# 定義一個與父類方法重名父的方法,在此方法上新增自己的內(nèi)容
def earn_money(self, work):
# 在與父類同名方法的內(nèi),想調(diào)用父類的同名方法,使用super(超類)
print(f'使用父類方法:{super().earn_money(work)}')
print(f'{self.name} 通過投資理財再賺了2000塊錢??!') # 在父類的基礎(chǔ)上,額外增加的
# 完全重寫
# def earn_money(self, work1):
# # 在與父類同名方法,但是我要完全重寫。不用父類的代碼。
# print("{} 通過 {} 來賺米米!".format(self.name, work1))