前言
這應該纔是大家心目中的面向對象編程叭(哈哈)
不過我們程序猿中很大一部分可能沒有這個福利,當你真正學好了一門技術,能用他來賺錢養活自己,給身邊的人更好的生活的時候,或許你就可以心安理得的“面向對象”了。
Python設計之初就是一門面向對象的語言,正因爲如此,在Python中創建一個類的對象是很容易的,學過C++和Java的同學對面向對象應該比較瞭解,在面向對象編程中萬物皆對象。更多具體的詳細的信息大家可以查閱專業的書籍或者博文。
面向對象簡介
- 類(class):用來描述具有相同屬性和方法的對象的集合。
- 對象:對象是類的實例。
- 方法:類中定義的函數。
- 實例化:創建一個類的實例,類的具體對象。
- 類變量:類變量在整個實例化對象中是公用的,類變量定義在類中且在函數體之外,類變量通常不作爲實例變量使用
- 數據成員:類變量或者實例變量用於處理類及其實例對象的相關數據。
- 方法重寫:如果父類方法不能滿足子類要求,可以對父類的方法進行改寫。
- 局部變量:定義在方法中的變量,只作用於當前實例的類。
- 實例變量:在類的聲明中,屬性是用變量來表示的,這種變量就稱爲實例變量,實例變量就是一個self修飾的變量。
- 繼承:一個派生類繼承基類的字段和方法,使用其屬性和方法,也可以有自己特有的屬性和方法。
第一個面向對象程序
Cat是一個類,裏面有兩個方法:eat()和drink();tom是一個Cat的對象,他可以調用drink和eat方法。
在Python的類方法中,永遠都有一個self參數。
class Cat:
def eat(self):
print("小貓愛喫魚")
def drink(self):
print("小貓要喝水")
# 創建貓對象
tom = Cat()
tom.eat()
tom.drink()
print(tom)
addr = id(tom)
print(addr)
# 運行結果
小貓愛喫魚
小貓要喝水
<__main__.Cat object at 0x7f4e631de828>
139974647081000
類的初始化方法
類的初始化方法是__init__()方法,使用類名創建對象時,會自動調用__init__()方法。__ init__()方法類似於C++中的構造函數,用於對象的初始化。
class Cat:
def __init__(self, new_name):
print("這是一個初始化方法")
# self.屬性名 = 屬性的初始值
# self.name = "Tom"
self.name = new_name
def eat(self):
print("%s愛喫魚" % self.name)
# 使用類名()創建對象的時候,會自動調用初始化方法__init__
tom = Cat("Tom")
print(tom.name)
lazy_cat = Cat("大懶貓")
lazy_cat.eat()
# 運行結果
這是一個初始化方法
Tom
這是一個初始化方法
大懶貓愛喫魚
類的對象回收方法和字符串方法
對象回收也就是:__ del __ ()方法,字符串方法是: __ str __ ()方法,這個名字可能起的不太對,但是就是這麼個意思。__ del __ ()方法類似於析構函數,__ str __()方法是爲了在開發中使用print輸出對象變量時,能夠打印自定義的內容。(__跟del中間沒有空格的,這個編輯器有問題)
class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s來了" % self.name)
def __del__(self):
print("%s去了" % self.name)
def __str__(self):
# 必須返回一個字符串
return "我是小貓[%s]" % self.name
tom = Cat("Tom")
print(tom)
# 運行結果
Tom來了
我是小貓[Tom]
Tom去了
私有屬性和方法
面向對象的特性就是:繼承,封裝,多態。私有屬性和方法就體現了其封裝性,在屬性和方法名前加上__,就表示這是一個私有屬性和方法,在對象內部可以訪問私有屬性,外界不能訪問。
class Women:
def __init__(self, name):
self.name = name
self.__age = 18
def secret(self):
print("%s的年齡是%d" % (self.name, self.__age))
xiaofang = Women("小芳")
# 私有屬性,在外界不能被直接訪問
# print(xiaofang.__age)
# 私有方法,同樣不允許在外界直接訪問
# xiaofang.secret()
單數如果我想要訪問的話應該怎麼辦呢?Python中允許使用"_+類名+私有屬性方法名"的方式來訪問私有屬性和方法。不過爲了保護類的封裝性,大家還是儘量不要使用這種方式。
繼承
Python繼承是面向對象編程中一個很重要的特性,繼承提高了代碼的重用,使得我們在編寫程序時能更加的省時省力,提高編程的效率。下面的代碼中,Animal類是一個父類,Dog類是繼承自Animal的一個子類,Dog類中有Animal類裏面所有的屬性和方法,所以當我們用Dog類創建一個對象時,可以調用Animal類裏的方法。
class Animal:
def eat(self):
print("喫---")
def drink(self):
print("喝---")
def run(self):
print("跑---")
def sleep(self):
print("睡---")
class Dog(Animal):
def bark(self):
print("汪汪叫")
# 創建一個對象——狗對象
wangcai = Dog()
wangcai.eat()
wangcai.drink()
wangcai.run()
wangcai.sleep()
wangcai.bark()
# 運行結果
喫---
喝---
跑---
睡---
汪汪叫
繼承具有傳遞性,也就是說父類可以派生出子類,子類還可以派生出子類的子類,也就是父類的孫子類…孫子類繼承有父類的所有屬性和方法,也繼承有父類的父類所有的屬性和方法。需要注意的是:這種傳遞性是順着一條線來傳遞的,假如父類派生出了另一個子類,他原先那個子類的子類就不能訪問這個“叔叔類”裏面特有的屬性和方法。
重寫父類方法:
子類中可以直接重寫父類的方法,當用這個子類創建對象的時候,會直接調用子類中重寫的方法,不會調用父類的方法。
擴展子類父類方法:
如果我覺得父類中的方法是可以被我再利用的,但是也要添加一些新的東西,這時候我們可以使用super()方法調用原本封裝在父類中的方法,也可以使用父類名.方法名(self)的方式。
父類的私有屬性和方法:
一般情況下,子類是不能直接調用父類的私有屬性和方法的,但是可以通過其公有方法間接地訪問父類的私有屬性和方法。
多繼承:
Python一個子類可以繼承多個父類,叫做多繼承,這樣就涉及到調用順序的問題了,在Python中子類先調用排在前面的父類,例如:A(B,C),A類繼承自B類和C類,A類對象會先調用B類中的方法。
class A:
def test(self):
print("A---test方法")
def demo(self):
print("A---demo方法")
class B:
def test(self):
print("B---test方法")
def demo(self):
print("B---demo方法")
class C(B, A):
"""多繼承可以讓子類對象,同事具有多個父類的屬性和方法"""
pass
# 創建子類對象
c = C()
c.test()
c.demo()
# 確定C類對象調用方法的順序
print(C.__mro__)
# 運行結果
B---test方法
B---demo方法
(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
多態
多態是不同的子類對象調用相同的父類方法,產生不同的執行結果。
- 多態可以增加代碼的靈活度。
- 以繼承和重寫父類方法爲前提。
- 是調用方法的技巧,不會影響到類的內部設計。
class Dog(object):
def __init__(self,name):
self.name = name
def game(self):
print("%s 蹦蹦跳跳的玩耍..." % self.name)
class XiaoTianQuan(Dog):
def game(self):
print("%s飛到天上去玩耍..." % self.name)
class Person(object):
def __init__(self, name):
self.name = name
def game_with_dog(self, dog):
print("%s和%s快樂的玩耍..." % (self.name, dog.name))
# 讓狗玩耍
dog.game()
# 1.創建一個狗對象
# wangcai = Dog("旺財")
wangcai = XiaoTianQuan("飛天旺財")
# 2.創建一個小明對象
xiaoming = Person("小明")
# 3.讓小明調用和狗玩的方法
xiaoming.game_with_dog(wangcai)
類屬性,類方法和靜態方法
類屬性就是給類對象中定義的屬性,何爲類對象?Python中的類就是一個特殊的對象,類對象只有一個,然而類創建出來的對象有很多個。類屬性通常用來記錄與這個類相關的特徵,不會記錄具體對象的特徵。類方法同理。一般使用類名.的方式訪問類屬性,不建議使用對象.的方式,對象.並不會改變類屬性的值:
class Tool(object):
# 使用賦值語句定義類屬性,記錄所有工具對象的數值
count = 0
def __init__(self, name):
self.name = name
# 讓類屬性的值+1
Tool.count +=1
# 1.創建工具對象
tool1 = Tool("斧頭")
tool2 = Tool("榔頭")
tool3 = Tool("水桶")
# 2.輸出工具對象的總數
tool3.count = 99
print("工具對象總數%d" % tool3.count)
print("===>%d" % Tool.count)
# 運行結果
工具對象總數99
===>3
使用類方法要加修飾器,具體參照下面的代碼:
class Tool(object):
# 使用賦值語句定義類屬性,記錄所有工具對象的數值
count = 0
@classmethod
def show_tool_count(cls):
print("工具對象的數量%d" % cls.count)
def __init__(self, name):
self.name = name
# 讓類屬性的值+1
Tool.count +=1
# 創建工具對象
tool1 = Tool("斧頭")
tool2 = Tool("榔頭")
# 調用類方法
Tool.show_tool_count()
# 運行結果
工具對象的數量2
靜態方法是一個既不需要訪問實例屬性或者調用實例方法,也不需要訪問類屬性或者類方法的一個方法。其定義在@staticmethod之後。
class Dog(object):
@staticmethod
def run():
# 不需要訪問實例/類屬性
print("小狗要跑...")
# 通過類名,調用靜態方法,不需要創建對象
Dog.run()
最後
有篇文章被推到首頁了!希望和大家一起進步!!!有錯的地方歡迎指正!