您好,登錄后才能下訂單哦!
注重對象和指責,不同的對象承擔各自的指責
更加適合對復雜的需求變化,專門應對復雜項目開發,提供固定的套路
面向對象強調的是誰來做,面向過程強調的如何做
類是對一群具有相同特征或者行為的事物統稱,是抽象的,不能直接使用,特征被稱為屬性,行為被稱為方法,類就是一個模板
對象是由類創建出來的一個具體存在,可以直接使用,通過哪個類創建出來的實例,就擁有哪個類中定義的特征和行為
類是模板,對象是根據類這個模板創建出來的,先有類,再有對象
類只有一個,對象有多個
類中定義的方法屬性都會存在對象中,不多不少
不同的對象之間的屬性不盡相同
方法名 | 類型 | 作用 |
---|---|---|
new | 方法 | 通過類()創建對象時,向內存申請空間,并將對象引用傳遞給init |
init | 方法 | 對象初始化時,會調用此方法 |
del | 方法 | 對象被銷毀時,會調用此方法 |
str | 方法 | 返回對象的描述信息 |
class Cat:
"""這是一個貓類"""
def eat(self):
print("小貓愛吃魚")
def drink(self):
print("小貓在喝水")
tom = Cat()
tom.drink()
tom.eat()
對象中的self參數
在類封裝的方法內部,self就表示當前調用方法的對象自己
調用方法時,不需要傳遞self參數
在方法內部可以通過self.訪問對象的屬性
也可以通過self.調用其他的對象方法
class Cat:
def __init(self,name)
self.name = name
def eat(self):
print("%s 愛吃魚" % self.name)
tom = Cat('mimimi')
tom.eat()
封裝是面向對象編程的一大特點
面向對象將屬性和方法封裝到一個抽象的類中
外部使用類創建對象,然后讓對象調用方法
對象方法的細節都被定義到類的內部
DFS(深度優先算法):
class E:
def say(self):
print('E')
class D:
pass
class C(E):
pass
class B(D):
pass
class A(B,C):
pass
a = A()
a.say()
# 查找順序 A->B->D->C->E
BFS(廣度優先算法):
class E:
def say(self):
print('E')
class D:
pass
class C(E):
pass
class B(D):
pass
class A(B,C):
pass
a = A()
a.say()
# 查找順序 A->B->C->D->E
C3(算法):
class F:
def say(self):
print('F')
class E(F):
pass
class D(F):
pass
class C(E):
pass
class B(D):
pass
class A(B,C):
pass
a = A()
a.say()
print(A.__mro__) # (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class '__main__.F'>, <class 'object'>)
# 查找順序 A->B-?>D-C->E-F
Python中不支持多態,也不用支持多態,Python是一種多態語言,崇尚鴨子類型,鴨子類型的概念來自于:“當看到一只鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那么這只鳥就可以被稱為鴨子,Python不會檢查類型是不是鴨子,只要它擁有鴨子的特征,就可以被正確的調用
class Duck:
def speak(self):
print('嘎嘎嘎...')
class Dog:
def speak(self):
print('汪汪汪...')
class Cat:
def speak(self):
print('喵喵喵...')
animal = []
animal.append(Duck)
animal.append(Dog)
animal.append(Cat)
for i in animal:
i().speak()
# 嘎嘎嘎...
# 汪汪汪...
# 喵喵喵...
實例方法第一個參數必須是self,通過實例方法來傳遞實例的屬性和方法,只能同實例來調用,靜態方法使@staticmethod裝飾器來定義,參數隨意,靜態方法是一個獨立的函數,它僅僅依托于類的命名空間,不會涉及到類是屬性和方法的作,靜態方法因為沒有參數綁定到該類所以僅僅提供函數功能,不能調用實例屬性或靜態屬性,類方法使用@classsmethod來定義,第一個參數必須是cls,通過它傳遞類的屬性和方法,類方法只能調用靜態屬性
class Data():
def __init__(self,year,month,day):
self.year = year
self.month = month
self.day = day
@staticmethod
def static_method(date_str):
year,month,day = tuple(date_str.split('-'))
return Data(int(year),int(month),int(day))
@classmethod
def class_method(cls,date_str):
year, month, day = tuple(date_str.split('-'))
return cls(int(year), int(month), int(day))
def object_method(self):
print(self.year,self.month,self.day,sep='-')
if __name__ == '__main__':
date = Data(2018,9,15)
date.object_method() # 2018-9-15
date = Data.class_method('2018-9-16')
date.object_method() # 2018-9-16
date = Data.static_method("2018-9-17")
date.object_method() # 2018-9-17
類變量,可以通過類調用,也可以通過實例調用,在內存中之存在一份
實例變量,只能通過實例調用,每個對象都有一份
class Person:
country = "中國"
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Person('kernel',18)
print(p1.name) # kernel
print(p1.age) # 18
print(p1.country) # 中國
print(Person.country) # 中國
p1.country = "美國" # 當通過對象修改類變量時,將會在該對象創建一個和類變量同名的變量,類變量依然不變
print(p1.country) # 美國
print(Person.country) # 中國
p2 = Person('alex',38)
print(p2.name) # alex
print(p2.age) # 38
print(p2.country) # 中國
class User:
def __init__(self,name,age):
self.name = name
self.__age = age
def get_age(self):
print(self.__age)
def set_age(self,age):
self.__age = age
if __name__ == '__main__':
u = User('kernel',18)
# print(u.__age) # AttributeError: 'User' object has no attribute '__age' 好吧,私有屬性不讓我訪問,但是真的無法訪問嗎
print(u._User__age) # 但這又是什么鬼呢?當然我們不建議這么干
u.set_age(19)
u._User__age=20 # 當然,設置也可以這樣
u.get_age() # 20
使用類名()創建對象,首先會調用new方法為對象分配空間,它的主要作用就是在內存中為對象分配空間和返回對象的引用,Python解釋器得到對象的引用后,將引用傳遞給init
定義一個類屬性,初始值是None,用于記錄單例對象的引用
重寫new方法
如果類屬性是None,調用方法申請空間,并在類屬性中記錄
返回類屬性中紀錄的對象引用
class MusicPlayer(object):
instance = None # 記錄第一個被創建對象的引用
init_flag = False # 記錄是否執行過初始化動作
def __new__(cls, *args, **kwargs):
if cls.instance is None:# 判斷類屬性是否是空對象
cls.instance = super().__new__(cls) # 調用父類的方法,為第一個對象分配空間
return cls.instance # 返回類屬性保存的對象引用
def __init__(self):
if not MusicPlayer.init_flag:
MusicPlayer.init_flag = True
player1 = MusicPlayer() # <__main__.MusicPlayer object at 0x0000017C297F99E8>
print(player1)
player2 = MusicPlayer() # <__main__.MusicPlayer object at 0x0000017C297F99E8>
print(player2)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。