2012年12月4日 星期二

甚麼是類別?

定義類別
========
class Message:
    def __init__(self, aString):
        self.text = aString
    def printIt(self):
        print self.text

__init__建構子是一個特殊的方法。任何變數被指定給這個方法將在建立新物件時變數範圍為新物件。在Python中特殊方法之名稱格式為__xxx__。
兩個方法第一個參數定為self。self指的是物件實體。這個參數會由執行時的解譯器給填上,非由程式設計師填上。
Message開頭第一個字母為大寫。這是一種傳統用法。另一種傳統用法是方法名稱第一個字為小寫,之後任何字開頭第一個字母都為大寫。

使用類別
========
m1 = Message("Hello world")
m2 = Message("So long, it was short but sweet")

note = [m1, m2] # put the objects in a list
for msg in note:
    msg.printIt() # print each message in turn
self是什麼?
javascript有相同的觀念不過名稱以this代替。
self是現行實例之參考。當建立一個類別實例就會有一份資料拷貝,但方法就沒有。當傳送一個訊息到實例會呼叫相關方法,他藉由內部參照到類別。他傳遞一個參照到他自己。
一個訊息傳遞給物件發生了什麼事:
1.程式碼產生一個物件。
2.物件呼叫類別方法,傳參照給他自己。
3.類別方法使用傳參照撿起物件資料給接收的物件。


多型
====
兩個物件有相同的方法名稱,但他們所屬的物件方法(方法的內容)都不同。稱為多型。
class Square:
    def __init__(self, side):
        self.side = side
    def calculateArea(self):
        return self.side**2

class Circle:
    def __init__(self, radius):
        self.radius = radius
    def calculateArea(self):
        import math
        return math.pi*(self.radius**2)

建立一個形狀列表並印出他們的面積:
list = [Circle(5),Circle(7),Square(9),Circle(3),Square(12)]

for shape in list:
    print "The area is: ", shape.calculateArea()

可以把類別定義為一個模組名shapes.py,然後import這個模組來操作它。

繼承
====
一個類別可以從一個parent或super類別繼承屬性與方法。這意味著新的類別不用實做所有的方法,也能藉由重載將已有的方法重新改寫。(像上面的calculateArea方法)
一個銀行帳戶的類別階層,我們可以存錢,取得餘額、存款。帳戶提供利息。
The BankAccount class
---------------------
銀行帳戶能做的事抽象層:
存錢 提錢 查看餘額 轉帳
要支援這樣的操作我們要有一個銀行帳號ID和現有的餘額。

建立類別
class BalanceError(Exception): 
      value = "Sorry you only have $%6.2f in your account"

class BankAccount:
    def __init__(self, initialAmount):
       self.balance = initialAmount
       print "Account created with balance %5.2f" % self.balance

    def deposit(self, amount):
       self.balance = self.balance + amount

    def withdraw(self, amount):
       if self.balance >= amount:
          self.balance = self.balance - amount
       else:
          raise BalanceError, BalanceError.value % self.balance

    def checkBalance(self):
       return self.balance
       
    def transfer(self, amount, account):
       try: 
          self.withdraw(amount)
          account.deposit(amount)
       except BalanceError:
          print BalanceError.value

物件資料模型

沒有留言: