面向對象:Object Oriented Programming,簡稱OOP,即面向對象程序設計。
類(Class)和對象(Object)
類是用來描述具有相同屬性和方法對象的集合。對象是類的具體實例。
比如,學生都有姓名和分數,那么這個姓名和分數就是共同的屬性,這時就可以設計一個類,用來記錄學生的姓名和成績。
這里解釋一下屬性和方法
- 屬性:Attribute,用來描述所有對象公有的屬性,如學生的姓名和分數。
- 方法:Method,包含在類里面的函數,也叫類函數,區別于類之外的函數,用來實現某些功能,比如打印出學生的姓名和分數。
使用關鍵詞class來創建一個類
class Student():
def __init__(self,name,score):
self.name = name
self.score = score def out(self):
print("%s:%s"%(self.name,self.score)
以上案例中,只是定義了一個類,電腦并沒有創建存儲空間。
只有完成類的實例化,才能創建出類的具體的對象,并為之分配存儲空間。所以說,對象是類的一個實例。 接下來創建一個對象,只需要添加一下兩行代碼即可實現
Student1 = Student('Anny','100')
Student2 = Student('Mike','90')
這樣一來,Student是類,student1和student2是創建的這個類的具體的對象。當有以上代碼的時候,Python/ target=_blank class=infotextkey>Python會自動調用init初始自構函數來創建具體的對象。關鍵字self是非常重要的參數,代表創建了函數本身。
當創建了具體的對象之后,就可以使用Student1.name和Student1.score來分別獲取該學生的姓名和分數,也可以直接調用方法Student1.out()來獲取所有信息。
類變量與實例變量
假設現在需要添加一個計數器,每當添加一個學生時計數器就加1。
這個計數器不屬于某一個學生,而是屬于類的屬性,所以稱之為類。
而姓名和分數是屬于每個學生的,所以稱之為實例變量,也叫對象變量。 正常情況下,這樣添加一個計數器
class Student():
number = 0
def __init__(self,name,score):
self.name = name
self.score = score
number = number + 1
def show(self):
print("%s:%s"%(self.name,self.score))
student1 = Student('Anny',100)
student2 = Student('Mike',90)
print(student1.name)
這里的number是類變量,所以將其放置方法外邊,name和score是實例變量,所以將其放置方法里面。
類變量和實例變量區別很大,訪問方式也不一樣。
類變量:class variables,類變量在整個實例化的對象中是公用的,類變量定義在類中,且在函數體外。訪問或者調用類變量的具體方法是類名.變量名,或者self.class.變量名,self.class.自動返回每個對象的類名。 實例變量:instance variables,定義在函數之內的變量,屬于某個具體的對象,訪問或者調用實例變量的方法是對象名.變量名,或者self.變量名。
執行上述代碼會發現報錯 UnboundLocalError: local variable 'number' referenced before assignment 英語賊差,某道云翻譯的:大致意思是局部變量number的引用之前的任務, 所以說,如果要調用屬于類的變量number,則使用Student.number或者self.class.number
修改如下:
class Student():
number = 0
def __init__(self,name,score):
self.name = name
self.score = score
Student.number = Student.number + 1
def show(self):
print("%s:%s"%(self.name,self.score))
student1 = Student('Anny',100)
student2 = Student('Mike',90)
student1.show()
print(student2.number)
類方法
有些變量只屬于類,有些方法也只屬于類,不屬于具體的對象。不難發現,在屬于對象的方法里面都有self的參數,比如init(self)、show(self)等,而在類中,則使用cls,與self類似,它表示類本身,一般加上@classmethod的修飾符以作說明。
這里使用自定義的類方法來打印學生的數量
class Student():
number = 0
def __init__(self,name,score):
self.name = name
self.score = score
Student.number = Student.number + 1
def show(self):
print("%s:%s"%(self.name,self.score)) @classmethod
def people(cls):
print("一共有%s名學生"%Student.number)
student1 = Student('Anny',100)
student2 = Student('Mike',90)
student1.show()
student2.show()
Student.people()
類的私有屬性和私有方法
類里面的私有屬性和私有方法都是以雙下劃線__開頭的,私有屬性和方法不能在類的外部直接使用或訪問。將score變為私有屬性,然后print(Student.score),就會發現報錯。但是調用show的時候不會報錯,這是因為show是類里面的函數,所以可以訪問私有變量。
私有方法也是同樣的道理,值得注意的是,私有方法必須含有self參數并且將其作為第一個參數。
在面向對象的編程中,通常很少讓外部類直接訪問類內部的屬性和方法,而是向外部提供一些按鈕,對其內部的成員進行訪問,以保證程序的安全性,這就叫封裝。
@property
def scores(self):
print("該學生成績為%s"%self.score)
加上裝飾器之后不用加括號可直接調用。
類的繼承
面向對象編程最大的好處就是避免重復的代碼,也就是將一段代碼重復使用,方法之一就是繼承。
先定義一個基類或者父類,再通過class 類名(父類):pass創建子類,這樣一來,子類獲得了父類的所有屬性和方法,這種現象就叫做繼承。
再寫段代碼,用Schoolmember表示父類,姓名和年齡是所有人的屬性,然而老師有工資(salary)這個專有屬性,學生有分數(score)這個專有屬性
# 創建父類學校成員SchoolMemberclass SchoolMember:
def __init__(self, name, age):
self.name = name
self.age = age def tell(self):
# 打印個人信息
print('Name:"{}" Age:"{}"'.format(self.name, self.age), end=" ")# 創建子類老師 Teacherclass Teacher(SchoolMember):
def __init__(self, name, age, salary):
SchoolMember.__init__(self, name, age) # 利用父類進行初始化
self.salary = salary # 方法重寫
def tell(self):
SchoolMember.tell(self)
print('Salary: {}'.format(self.salary))# 創建子類學生Studentclass Student(SchoolMember):
def __init__(self, name, age, score):
SchoolMember.__init__(self, name, age)
self.score = score def tell(self):
SchoolMember.tell(self)
print('score: {}'.format(self.score))
teacher1 = Teacher("John", 44, "$60000")
student1 = Student("Mary", 12, 99)
teacher1.tell() # 打印 Name:"John" Age:"44" Salary: $60000student1.tell() # Name:"Mary" Age:"12" score: 99
通過以上代碼不難看出
- 在創建子類的過程中,需要手動調用父類的構造函數init來完成子類的創建。
- 在子類中調用父類的方法時,需加上父類的類名前綴,且必須帶self參數變量。例SchoolMember.tell(self)。
- 如果子類調用了每個方法或者屬性,Python會先在父類中尋找,找不到就會去子類尋找。
==在實際的項目中,一個子類可以繼承多個父類。==
使用super()關鍵字調用父類
在子類中可以使用super關鍵字直接調用父類中的屬性或者方法,簡化代碼,也反映出人生苦短,我用Python的宗旨。
# 創建子類學生Studentclass Student(SchoolMember):
def __init__(self, name, age, score):
SchoolMember.__init__(self, name, age)
self.score = score def tell(self):
super().tell() # 等同于 SchoolMember.tell(self)
print('score: {}'.format(self.score))
以上的例子中,學生子類調用了父類的tell方法,等同于SchoolMember.tell(self),使用super關鍵字調用時,需去掉括號里的self。
本次的分享就到這啦,如果對您有幫助的話,麻煩點個關注再走吧~感謝閱讀。