1. 程式人生 > >學習筆記九 面向物件程式設計

學習筆記九 面向物件程式設計

一.面向物件技術簡介:

  • 類(Class): 用來描述具有相同的屬性和方法的物件的集合。它定義了該集合中每個物件所共有的屬性和方法。物件是類的例項。
  • 類變數:類變數在整個例項化的物件中是公用的。類變數定義在類中且在函式體之外。類變數通常不作為例項變數使用。
  • 資料成員:類變數或者例項變數用於處理類及其例項物件的相關的資料。
  • 方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱為方法的重寫。
  • 例項變數:定義在方法中的變數,只作用於當前例項的類。
  • 繼承:即一個派生類(derived class)繼承基類(base class)的欄位和方法。繼承也允許把一個派生類的物件作為一個基類物件對待。例如,有這樣一個設計:一個Dog型別的物件派生自Animal類,素以Dog也是一個Animal。
  • 例項化:建立一個類的例項,類的具體物件。
  • 方法:類中定義的函式。
  • 物件:通過類定義的資料結構例項。物件包括兩個資料成員(類變數和例項變數)和方法。

二.類:

  三種定義類的方式:

class My:  #經典類
    pass

class My2(object):  #新式類
    pass

class My3(): #新式類
    pass

簡單例子:定義一個叫MyDb資料庫操作類,裡面包含資料庫的一些方法。

 1 class MyDb:
 2     def __init__(self,host,user,password,db,port=3306,charset='
utf8'):#建構函式, 3 print('連線資料庫') 4 self.conn = pymysql.connect(host=host,user=user,password=password, 5 db=db,port=port,charset=charset) 6 self.cur = self.conn.cursor() 7 8 def execute_one(self,sql): 9 print('返回單條資料') 10 self.cur.execute(sql)
11 res = self.cur.fetchone() 12 return res 13 14 def execute_many(self,sql): 15 print('返回多條資料的') 16 self.cur.execute(sql) 17 res = self.cur.fetchall() 18 return res 19 20 def __del__(self):#解構函式 21 print('關閉資料庫連線') 22 self.cur.close() 23 self.conn.close() 24 25 my = MyDb('192.168.1.40','jxz','123456','jxz') #例項化 26 27 #一個變數前面加了self之後,那麼在這個類裡面的其他的函式都可以用了。 28 29 res = my.execute_one('select * from app_myuser where username="testuser1";') 30 print(res) 31 32 res2 = my.execute_many('select * from app_myuser limit 10;') 33 34 print(res2)

其中__init__和__del__分別是建構函式和解構函式。建構函式是在例項化時候被呼叫,一般都是為這個例項化物件賦初始值,解構函式是在這個物件生命週期結束的時候呼叫。他們預設都是自動呼叫。但是也有顯示呼叫。

__init__()方法是可選的,如果不提供,Python 會給出預設的__init__方法。

__del__()也是可選的,如果不提供,則Python 會在後臺提供預設解構函式如果要顯式的呼叫解構函式,可以使用del關鍵字,方式如下:

del 物件名   三.例項方法,類方法,靜態方法,屬性方法,私有方法:
 1 class Car:
 2     wheel = 4 #類變數
 3     def __init__(self,color,p):
 4         self.color = color #例項變數
 5         self.p = p
 6 
 7     def help(self):
 8         print('汽車有%s個輪子'%self.wheel)
 9         print('汽車的顏色是%s'%self.color)
10         print('牌子%s'%self.p)
11         print('='*10)
12         self.haha()
13         self.check_wheel()
14 
15     @classmethod
16     def check_wheel(cls):#類方法
17         print('cls的記憶體地址',id(cls))
18         print(cls.wheel)
19         cls.haha()
20 
21     @classmethod
22     def haha(cls):
23         print('哈哈哈')
24         cls.help2()
25 
26     @staticmethod
27     def help2():#靜態方法
28         print('這個類的作用是造汽車,它裡面有xxx方法')
29 
30     @property
31     def yesterday(self):#屬性方法
32         import datetime
33         res = datetime.date.today()  + datetime.timedelta(-1)
34         return str(res)
35 
36     def tom(self):
37         import datetime
38         res = datetime.date.today()  + datetime.timedelta(1)
39         return str(res)

 例項屬性:類裡的例項方法的第一個引數必須為self,這是例項方法的唯一標誌。可以理解為self就是例項本身,因此例項方法必須在例項化後才可以呼叫(因為不例項化就是不存在的)。各個例項有自己獨立的例項空間,存放自己的例項屬性(變數和方法)。所以在例項化後,可以新增例項屬性(例項變數)。例項方法裡面可以隨便通過self來呼叫例項方法,類方法,靜態方法,類變數。

 類屬性:包括方法和變數,類方法必須由@classmethod裝飾,並且方法的第一個引數必須是cls,不需要例項化就可以呼叫,類屬性的空間和例項屬性的空間是獨立的,一個類的屬性空間只有一個,雖然類屬性可以被其他物件訪問,但是由於空間獨立,類屬性只能由類自己修改,例項可以訪問,無權修改。

1 Car.help2()
2 mcb = Car('赤橙黃綠青藍紫','馬春波')
3 print(mcb.wheel)#例項沒有定義wheel的時候,預設使用類變數
4 mcb.wheel=8
5 print(mcb.wheel)#當例項定義了自己的wheel屬性的時候,使用的就是自己的wheel
6 print(Car.wheel)

結果:

這個類的作用是造汽車,它裡面有xxx方法
4
8
4

要注意的是:例項名.類屬性和類名.類屬性是兩個獨立的空間,值互不影響。

  靜態方法:不需要例項化就可以呼叫的,它就是一個定義在類裡面的普通函式,不能使用例項變數、例項方法、不能使用類變數、類方法。用@staticmethod裝飾,沒有必寫引數。一般用來列印資訊。

  私有方法:變數、函式,前面加兩個下劃線就代表是一個私有的,只能在類裡面用。在類外面就不能使用,只能通過類方法或者例項方法去修改。出於安全考慮,就是提供了修改或操作的接口才能進行修改,否則其他無權修改。

 1 class My:
 2     def test(self):
 3         self.__password = 123456
 4     def say(self):
 5         print('password',self.__password)
 6     def __set_password(self):
 7         self.__password = 7890
 8     def update(self):
 9         self.__set_password()
10 
11 m = My()
12 m.test()
13 m.say()
14 m.update()
15 m.say()
password 123456
password 7890

  屬性方法:用@property裝飾,改方法不允許帶引數,例如上述的yesterday(),作用就是在呼叫的時候省去括號,比如這個方法呼叫就是print(mcb.yesterday)。

 

四.繼承:

  子類可以繼承父類的方法而無需重新定義他們。繼承最大的好處是子類獲得了父類的全部功能。當然,也可以對子類增加一些方法。或者重寫父類的方法。

class Lm:
    money = 1000000
    house = 5
    def driver(self):
        print('會開車')

class Mcb(Lm):
    def about_me(self):
        print('我有 %s 錢 ,%s 房子'%(self.money,self.house))
        self.driver()

    def driver(self):#方法過載
        print('會開28個輪子的汽車')


m = Mcb()
m.driver()
m.about_me()

 

會開28個輪子的汽車
我有 1000000 錢 ,5 房子
會開28個輪子的汽車