一些概念
- 圍繞函數(shù)來設計程序的過程,叫做面向過程編程亡笑;
- 而面向對象編程侣夷,就是將數(shù)據(jù)與功能進行組合,并將其包裝在被稱為對象的物體內(nèi)仑乌。
- 類與對象是面向對象編程的兩個重要方面百拓。一個類(
class
)能夠創(chuàng)建新的類型(type
),對象(object
)就是類的實例(instance
). - 對象可以使用它的普通變量來存儲值晰甚,這個從屬于對象或類的變量叫做字段
Field
- 對象還可以使用累的某些函數(shù)來做一些操作衙传,這種函數(shù)叫做類的方法
Method
. - 字段和方法統(tǒng)稱類的屬性
- 字段有兩種類型:屬于一個類的各個實例或對象的叫做實例變量
Instance Variables
,屬于某一個類的叫做類變量Class Variables
self
self
用于區(qū)分類方法與普通厕九。
在類方法中蓖捶,必須有一個額外的名字來添加到參數(shù)列表的開頭,但是我們不用調用這個功能時就為這個參數(shù)進行賦值扁远,Python會
為它提供俊鱼。這種特定的變量引用的是對象本身刻像,被特定命名為self
.
于是,我們可以知道并闲,就算我們定義一個沒有參數(shù)的類方法细睡,它也是會有一個特定的參數(shù)self
.
(關于self不理解的,可以先放一下帝火,等把接下來的學習一下之后再回過來看就會好很多)
創(chuàng)建一個類和方法并使用
# 創(chuàng)建一個類溜徙,使用 'class + 類名'的形式
class MyFirstClass:
# 類方法
def Class_Method_Test(self):
print('我是一個類方法')
# 實例化一個對象并輸出相關信息
first = MyFirstClass()
print(first)
# 調用實例方法
first.Class_Method_Test()
輸出結果
<__main__.MyFirstClass object at 0x1010ea438>
我是一個類方法
Process finished with exit code 0
具體的請參考注釋。
__init__方法
__init__
方法會在一個類被實例化時立即調用购公,請參考下面的代碼
# 使用__init__方法
class MyClassDemo:
# 調用init方法萌京,并設置name,name2兩個傳入?yún)?shù)
def __init__(self,name,name2):
# 創(chuàng)建新字段name和myName接收和傳遞參數(shù)name、name2的值
print('3')
self.name = name
self.myName = name2
def getName(self):
# 在這里使用上面所創(chuàng)建新字段name宏浩、myName傳遞過來的值
print('4')
print('The name is:',self.name)
print('Other name is:',self.myName)
# 實例化對象知残,調用__init__方法,并傳入兩個參數(shù)的值
print('1')
demo = MyClassDemo('Ultraman Zero.','Ultraman Seven.')
# 調用類的方法
print('2')
demo.getName()
輸出結果
1
3
2
4
The name is: Ultraman Zero.
Other name is: Ultraman Seven.
Process finished with exit code 0
從上面的輸出比庄,可以看出程序運行的次序為:實例化一個對象 --> 調用__init__方法 --> 實例對象調用類方法求妹。
說明請參考注釋。
類變量與對象變量
字段有兩種形式:類變量與對象變量
類變量是共享的佳窑,它可以被這個類的所有實例對象使用制恍,當一個實例對象對它做出變化時,這種變化將會體現(xiàn)到這個類的所有實例對象中神凑。
對象變量由類的每一個單獨的實例變量擁有净神,一個類的實例變量對它做出改變時,其它類的實例對象不會發(fā)生變化溉委。對象變量不是共享的鹃唯,每個對象都有屬于它自己的字段的副本。
請參考下面的例子
class Reboot:
""" 創(chuàng)建一個類變量,用于計算數(shù)量 """
Population = 0;
"""
創(chuàng)建機器人的接口
每次創(chuàng)建一個機器人的實例對象瓣喊,Population的值就會+1
"""
def __init__(self,name):
self.rebootName = name
print(self.rebootName,' is Initialazing......')
Reboot.Population += 1
# 每次銷毀一個機器人坡慌,Population的數(shù)量就會-1
def reboot_die(self):
print(self.rebootName,' is being destorying....')
Reboot.Population -= 1
print('Now Reboot population = ',Reboot.Population)
if Reboot.Population < 1:
print('We have no Reboot.')
else:
print('We still have {:d} Reboots'.format(Reboot.Population))
def say_hi(self):
print("Hello,I'm {}".format(self.rebootName))
# 使用裝飾器Decorator來將方法標記為類方法
# 使用裝飾器等價于調用 how_manay=classmethod(how_manay)
@classmethod
def how_manay(cls):
print("We have {:d} reboots".format(cls.Population))
reboot0 = Reboot('Yiwa')
reboot0.say_hi()
print('\n')
reboot1 = Reboot('Yiwa1')
reboot1.say_hi()
print('\n')
reboot0.reboot_die()
Reboot.how_manay()
- 說明,如上代碼藻三,我們除了可以使用
Reboot.Population
之外洪橘,還可以使用self.__class_.Population
,因為每個對象都通過self.__class_.Population
來引用它的類。 - 還有棵帽,我們只能通過
self
來引用同一對象的變量和方法熄求。這種叫做屬性引用。 - 在Python中岖寞,所有類成員抡四,包括數(shù)據(jù)成員都是公開的,所有方法都是虛擬的。
- 我們還可以通過在數(shù)據(jù)成員名稱前面加"
__
"雙下劃線前綴指巡,這是Python
會使用命名調整來使其成為一個私有變量淑履。因此,我們需要遵循一個約定藻雪,所有在類或對象之中使用的變量秘噪,其命名應以下劃線開頭,其它所有非此格式的變量都是公開的勉耀,并且能被其它任何類或對象使用指煎。 除了雙下劃線這點,Python
并不會強制這樣做便斥。
繼承一個類
面向對象的一個優(yōu)點就是代碼重用(Reuse
)至壤。重用的一種實現(xiàn)方式就是通過繼承機制(Inheritance
)。繼承是在類之間實現(xiàn)類型(Type
)與子類型(Subtype
)的工具枢纠。
請看下面的例子
# base class
class SchoolManager:
# 共有的屬性 name age
def __init__(self,name,age):
self.userName = name
self.userAge = age
def tellMe(self):
print("Initialztion manaher:{},age:{}".format(self.userName,self.userAge))
# subclass
class Teacher(SchoolManager):
# salary 子類私有屬性
def __init__(self,name,age,salary):
SchoolManager.__init__(self,name,age)
self.userSalary = salary
print("Iniyialzation teacher,name:{},age:{}.salary:{}".format(self.userName,self.userAge,self.userSalary))
def tellMe(self):
# 這時候會調用一次基類的初始化方法
SchoolManager.tellMe(self)
print("{} salary is {}".format(self.userName,self.userAge))
# subclass
class Student(SchoolManager):
# grade子類私有屬性
def __init__(self,name,age,grade):
SchoolManager.__init__(self,name,age)
self.userGrade = grade
print("Initialzation student,name:{},age:{},grade:{}".format(self.userName,self.userAge,self.userGrade))
def tellMe(self):
# 這時候會調用一次基類的初始化方法
SchoolManager.tellMe(self)
print("{} grade is {}".format(self.userName,self.userGrade))
teacher = Teacher("mR.XXOO",18,45000)
student = Student("Tom",25,99)
print("\n")
member = [teacher,student]
for m in member:
m.tellMe()
print("\n")
輸出結果
Iniyialzation teacher,name:mR.XXOO,age:18.salary:45000
Initialzation student,name:Tom,age:25,grade:99
Initialztion manaher:mR.XXOO,age:18
mR.XXOO salary is 18
Initialztion manaher:Tom,age:25
Tom grade is 99
Process finished with exit code 0
如上像街,我們對SchoolManager
做出改變時,這種改變會反映到所有子類中晋渺,但是對Teacher
或Student
這兩個子類中的一個做出改變時都不會影響到其它子類镰绎。另外,Teacher
和Student
可以被看做SchoolManager
的對象加以引用木西。這被稱為多態(tài)(Polymorphism
)
我們重用父類中的代碼畴栖,不需要在其它子類中重復這些代碼。但是八千,當我們使用獨立類型時吗讶,才可以重復使用這些代碼。
當繼承元組中有多個類時恋捆,稱為多繼承或多重繼承关翎,如class Teacher(SchoolManager,UserOperation):
。