面向?qū)ο缶幊?Object-Oriented Programming
)介紹
OOP
編程是利用“類”和“對(duì)象”來創(chuàng)建各種模型來實(shí)現(xiàn)對(duì)真實(shí)世界的描述,使用面向?qū)ο缶幊痰脑蛞环矫媸且驗(yàn)樗梢允钩绦虻木S護(hù)和擴(kuò)展變得更簡單芥被,并且可以大大提高程序開發(fā)效率冗茸;
基于面向?qū)ο蟮某绦蚩梢允顾烁尤菀桌斫饽愕拇a邏輯顶捷,從而使團(tuán)隊(duì)開發(fā)變得更從容。
面向?qū)ο蟮膸讉€(gè)核心特性:
類 - Class
一個(gè)類即是對(duì)一類擁有相同屬性的對(duì)象的抽象践付、藍(lán)圖、原型。在類中定義了這些對(duì)象的都具備的屬性(variables(data))、共同的方法
對(duì)象 - Object
一個(gè)對(duì)象即是一個(gè)類的實(shí)例化后實(shí)例落萎,一個(gè)類必須經(jīng)過實(shí)例化后方可在程序中調(diào)用媒鼓,一個(gè)類可以實(shí)例化多個(gè)對(duì)象,每個(gè)對(duì)象亦可以有不同的屬性亮蛔,就像人類是指所有人芬探,每個(gè)人是指具體的對(duì)象宵蕉,人與人之前有共性,亦有不同
封裝 - Encapsulation
在類中對(duì)數(shù)據(jù)的賦值、內(nèi)部調(diào)用對(duì)外部用戶是透明的,這使類變成了一個(gè)膠囊或容器,里面包含著類的數(shù)據(jù)和方法
繼承 - Inheritance
一個(gè)類可以派生出子類馏予,在這個(gè)父類里定義的屬性冕香、方法自動(dòng)被子類繼承
多態(tài) - Polymorphism
多態(tài)是面向?qū)ο蟮闹匾匦?簡單點(diǎn)說:“一個(gè)接口愕难,多種實(shí)現(xiàn)”它褪,指一個(gè)基類中派生出了不同的子類老赤,且每個(gè)子類在繼承了同樣的方法名的同時(shí)又對(duì)父類的方法做了不同的實(shí)現(xiàn)祥楣,這就是同一種事物表現(xiàn)出的多種形態(tài)历葛。
Python就是一門面向?qū)ο蟮恼Z言
類定義
格式:
class ClassName(object):
.
.
.
實(shí)例:
class Dog(object):
print("it's a Dog class")
類對(duì)象
實(shí)例:
class MyClass(object):
"""一個(gè)簡單的類實(shí)例"""
# 屬性
num = 666
# 方法
def sayHello(self):
return 'hello world'
# 實(shí)例化類
x = MyClass()
# 訪問類的屬性和方法
print(x.i) # 666
print(x.f()) # hello world
構(gòu)造方法
很多類都傾向于將對(duì)象創(chuàng)建為有初始狀態(tài)的咒程。因此類可能會(huì)定義一個(gè)名為
__init__()
的特殊方法
class MyClass(object):
"""一個(gè)簡單的類實(shí)例"""
def __init__(self):
self.name = "Mazy"
# 實(shí)例化類
x = MyClass()
print(x.name) # Mazy
__init__()
方法可以有參數(shù),參數(shù)通過__init__()
傳遞到類的實(shí)例化操作上
class ComplexClass(object):
def __init__(self, a, b):
self._a = a
self._b = b
x = ComplexClass("Mazy", 666)
print(x._a, x._b) # 輸出結(jié)果:Mazy 666
self
代表類的實(shí)例刺洒,而非類
class Test:
def iprint(self):
print(self)
print(self.__class__)
t = Test()
t.iprint()
打印結(jié)果:
<__main__.Test object at 0x1022439e8>
<class '__main__.Test'>
類的方法
在類的內(nèi)部拇惋,使用
def
關(guān)鍵字來定義一個(gè)方法,與一般函數(shù)定義不同,類方法必須包含參數(shù)self
, 且為第一個(gè)參數(shù),self
代表的是類的實(shí)例
實(shí)例:
# 類定義
class people(object):
# 定義基本屬性
name = ""
age = 0
# 定義私有屬性,私有屬性在類外部無法直接進(jìn)行訪問
__weight = 0
# 定義構(gòu)造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def talk(self):
print("%s 說: 我 %d 歲。" % (self.name, self.age))
# 實(shí)例化類
p = people('Vivian', 21, 48)
p.talk() # Vivian 說: 我 21 歲禀横。
單繼承
格式:
class DerivedClassName(BaseClassName):
.
.
.
基類定義在另一個(gè)模塊中時(shí)這一點(diǎn)非常有用:
class DerivedClassName(modname.BaseClassName):
實(shí)例:
# 類定義
class people(object):
# 定義基本屬性
name = ""
age = 0
# 定義私有屬性,私有屬性在類外部無法直接進(jìn)行訪問
__weight = 0
# 定義構(gòu)造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def talk(self):
print("%s 說: 我 %d 歲抬闷。" % (self.name, self.age))
# 單繼承示例
class student(people):
grade = ''
# 重寫構(gòu)造函數(shù),添加參數(shù)
def __init__(self, n, a, w, g):
# 調(diào)用父類的構(gòu)函
people.__init__(self, n, a, w)
self.grade = g
# 覆寫父類的方法
def talk(self):
print("%s 說: 我 %d 歲了荤懂,我在讀 %d 年級(jí)" % (self.name, self.age, self.grade))
s = student("Eric", 8, 68, 3)
s.talk() # Eric 說: 我 8 歲了廊宪,我在讀 3 年級(jí)
多繼承
格式:
class DerivedClassName(Base1, Base2, Base3):
.
.
.
實(shí)例:
class baseClassA(object):
name = ""
def __init__(self, n):
self.name = n
def sayHi(self):
print("Hi ", self.name)
class baseClassB(object):
song = ""
def __init__(self, s):
self.song = s
def sing(self):
print("sing ", self.song)
class baseClassC(baseClassA, baseClassB):
hobby = ""
def __init__(self, n, s, h):
baseClassA.__init__(self, n)
baseClassB.__init__(self, s)
self.hobby = h
robot = baseClassC("Joy", "God is friend", "dance")
robot.sing() # sing God is friend
robot.sayHi() # Hi Joy
方法重寫
如果父類方法的功能不能滿足子類的需求,可在子類重寫你父類的方法
class Parent: # 定義父類
def myMethod(self):
print ('調(diào)用父類方法')
class Child(Parent): # 定義子類
def myMethod(self):
print ('調(diào)用子類方法')
c = Child() # 子類實(shí)例
c.myMethod() # 子類調(diào)用重寫方法
類屬性與方法
類的私有屬性
__private_attrs
:兩個(gè)下劃線開頭拐迁,聲明該屬性為私有,不能在類地外部被使用或直接訪問患雏。在類內(nèi)部的方法中使用時(shí) self.__private_attrs
。
類的方法
在類地內(nèi)部是鬼,使用def
關(guān)鍵字來定義一個(gè)方法偶芍,與一般函數(shù)定義不同,類方法必須包含參數(shù) self
穗泵,且為第一個(gè)參數(shù),self
代表的是類的實(shí)例膘螟。
self
的名字并不是規(guī)定死的,也可以使用 this
,但是最好還是按照約定是用 self
。
類的私有方法
__private_method
:兩個(gè)下劃線開頭,聲明該方法為私有方法,只能在類的內(nèi)部調(diào)用 祟昭,不能在類地外部調(diào)用踩萎。self.__private_methods
勿璃。
實(shí)例:
class Site:
__secretCount = 0 # 私有變量
publicCount = 0 # 公開變量
def __init__(self, name, url):
self.name = name # 公開屬性
self.__url = url # 私有屬性
def __foo(self): # 私有方法
print('這是私有方法')
def foo(self): # 公共方法
print('這是公共方法')
self.__foo()
類的專有方法總結(jié):
方法名 | 介紹 |
---|---|
__init__ |
構(gòu)造函數(shù),在生成對(duì)象時(shí)調(diào)用 |
__del__ |
析構(gòu)函數(shù)锹杈,釋放對(duì)象時(shí)使用 |
__repr__ |
打印竭望,轉(zhuǎn)換 |
__setitem__ |
按照索引賦值 |
__getitem__ |
按照索引獲取值 |
__len__ |
獲得長度 |
__cmp__ |
比較運(yùn)算 |
__call__ |
函數(shù)調(diào)用 |
__add__ |
加運(yùn)算 |
__sub__ |
減運(yùn)算 |
__mul__ |
乘運(yùn)算 |
__div__ |
除運(yùn)算 |
__mod__ |
求余運(yùn)算 |
__pow__ |
乘方 |
運(yùn)算符重載
對(duì)類的專有方法進(jìn)行重載
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2, 10) # 等效于:v1.a = 2, v1.b = 10
v2 = Vector(5, -2) # 等效于:v2.a = 5, v2.b = -2)
print (v1 + v2) # 等效于: v1.1 + v2.1, v1.b + b2.b
打印結(jié)果:
Vector (7, 8)