วันจันทร์ที่ 27 กุมภาพันธ์ พ.ศ. 2560

9.8 การรับทอด python

9.8 การรับทอด

การรับทอด

                จากความรู้พื้นฐานด้านการเขียนโปรแกรมเชิงวัตถุ ได้กล่าวถึง การรับทอดว่า เป็นการสืบทอดคลาส จากคลาสแม่ไปยังคลาสลูกได้ทั้งคุณสมบัติ แอตทริบิวต์ และเมท็อด การสร้างคลาสที่สืบทอดกันได้เนื่องจาก ในการสร้างคลาสขึ้นมาใหม่นั้นต้องสร้างทั้งแอตทริบิวต์และเมท็อดขึ้นมาใหม่ด้วยเสมอ แต่ถ้ากรณีที่คลาสมีลักษณะเหมือน ๆ กัน จึงไม่จำเป็น        ต้องสร้างทั้งแอตทริบิวต์และเมท็อดใหม่ขึ้นมาอีก เพียงแต่สร้างคลาส แล้วกำหนดให้รับการสืบทอดจากคลาสเดิมที่เหมือน ๆ กัน หรือเรียกว่า คลาสแม่ คลาสใหม่สร้างขึ้นมา เรียกว่า คลาสลูก ถ้าเขียนเป็น UML จะได้ดังภาพที่ 9.11

ภาพที่ 9.11  แสดง UML ของคลาสแม่และลูก

        จากภาพที่ 9.11 เป็นตัวอย่างคลาสสำหรับเก็บข้อมูลบัญชีของธนาคาร มีคลาสแม่ชื่อว่า  Account  ประกอบด้วยแอตทริบิวต์ balance ทำหน้าที่สำหรับเก็บข้อมูลเงินคงเหลือ และมีเมท็อดจำนวน 3 เมท็อดด้วยกัน ได้แก่ deposit() ใช้สำหรับให้เจ้าของบัญชีฝากเงินเพิ่ม      เมท็อด withdraw() สำหรับถอนเงิน และเมท็อด getBalance() สำหรับคำนวณเงินคงเหลือ 
                คลาส InterestAccount  เป็นคลาสที่ออกแบบมาเพื่อใช้กับการคิดดอกเบี้ยบัญชีเงินฝากแต่ละประเภท ซึ่งคลาสนี้มีแอตทริบิวต์ balance เหมือนกัน รวมทั้งเมท็อดก็เหมือนกันทั้งหมด ดังนั้นจะได้รับการสืบทอดมาจากคลาส Account จึงไม่จำเป็นต้องเขียนในคลาส InterestAccount  แต่มีเมท็อดใหม่เพิ่มขึ้นมา คือ เมท็อด add_monthly_interest() มีไว้สำหรับคำนวณดอกเบี้ย การเขียนโปรแกรมเพื่อสร้างคลาส Account จึงมีลักษณะดังภาพที่ 9.12

source code

class Account:
    'Bank Account'
    balance = 0.0

    # Constructor เปิดบัญชี
    def __init__(self, amount):
        self.balance = amount

    # ฝากเงิน
    def deposit(self, amount):
        self.balance += amount

    # ถอนเงิน
    def withdraw(self, amount):
        if self.balance >= amount:
            self.balance -= amount
            return self.balance
        else:
            self.balance = 0.0
            return self.balance

    # ยอดเงินคงเหลือ
    def getBalance(self):
        return self.balance
ภาพที่ 9.12  แสดงคำสั่งสร้างคลาส Account

จากภาพที่ 9.12 เป็นคำสั่งสร้างคลาส ตามภาพที่ 9.11 เมื่อพิจารณาระหว่างภาพ UML กับคำสั่งจะแยกออกเป็น 3 ส่วน ได้แก่ ชื่อคลาส  แอตทริบิวต์ และเมท็อด มีรายละเอียดดังนี้
                        การประกาศชื่อคลาส  ใช้คำสั่ง class และชื่อของคลาส  
                        ประกาศแอตทริบิวต์ชื่อ balance กำหนดให้ค่าเริ่มต้นเท่ากับ 0.0 
                        เมท็อด มี 4 เมท็อดด้วยกัน คือ
                        1.  เมท็อดพิเศษหรือเรียกว่า คอนสตรักเตอร์ ที่มีอาร์กิวเมนต์ชื่อ amount ซึ่ง      อาร์กิวเมนต์นี้รับเข้ามาจะนำไปเก็บในตัวแปร  balance    
                        2.  เมท็อด deposit()  มีอาร์กิวเมนต์ชื่อ amount อาร์กิวเมนต์นี้รับเข้ามาจะนำไปบวกกับตัวแปร balance ผลลัพธ์ที่ได้เก็บไว้ในตัวแปร  balance 

                     3. เมท็อด withdraw()  มีอาร์กิวเมนต์ชื่อ amount  และมีการตรวจสอบเงื่อนไขก่อน คือ ในกรณี balance มากกว่า amount ให้นำไปลบกับตัวแปร balance ได้เลย ผลลัพธ์      ที่ได้เก็บไว้ในตัวแปร  balance และส่งค่า balance กลับไปยังเมท็อดอื่น แต่ในกรณีที่ amount
มากกว่า balance กำหนดให้ balance เท่ากับ 0.0  และส่งค่า balance  ไปยังเมท็อดอื่นเช่นกัน
                        4.  เมท็อด getBalance() ไม่มีอาร์กิวเมนต์รับค่า แต่เป็นการส่งค่า balance ไปยังเมท็อดอื่น
                การสร้างคลาสลูก หรือ InterestAccount สามารถเขียนต่อจากคลาสแม่ได้เลย แต่วิธีการบอกให้รู้ว่าสืบทอดมาจากคลาสแม่โดยการบอกชื่อคลาสแม่อยู่ภายในวงเล็บ ดังนี้   class InterestAccount(Account):  ตัวอย่างการเขียนคำสั่งสร้างคลาสลูก ดังภาพที่ 9.13 

source code

class InterestAccount(Account):
    'InterrestAccount is a child class of Account'
    default_interest = 6.5

    def __init__(self, *args):
        if(len(args)==0):
            self.balance = 0.0
            print "เปิดบัญชีอย่างเดียว"
        elif(len(args)==1):
            self.interest_rate = self.default_interest
            print "เปิดบัญชีพร้อมฝาก รับดอกเบี้ยปกติ"
        else:
            self.balance = args[0]
            self.interest_rate = args[1]
            print "เปิดบัญชีได้รับดอกเบี้ยพิเศษ"

    def add_monthly_interest(self):
        if self.balance==0:
            self.balance=0
        else:
            self.balance = self.balance+(self.balance*self.interest_rate/100.0/12)

ภาพที่ 9.13  แสดงคำสั่งการสร้างคลาส InterestAccount
        จากภาพที่ 9.13 การสร้างคลาสลูก เมื่อพิจารณาจากภาพที่ 9.11 จะประกอบด้วย 3 ส่วน ได้แก่ การประกาศชื่อคลาส แอตทริบิวต์ และเมท็อด มีรายละเอียดของคำสั่งดังนี้
             การประกาศชื่อคลาส ใช้คำสั่ง class และตามด้วยชื่อคลาส และชื่อคลาสที่ได้รับการสืบทอดมาซึ่งอยู่ภายในวงเล็บ
ประกาศแอตทริบิวชื่อ default_interest กำหนดให้ค่าเริ่มต้นเท่ากับ 6.5
                        มีเมท็อด ประกอบด้วย 2 เมท็อด คือ เมท็อดพิเศษหรือคอนสตรักเตอร์ และเมท็อดสำหรับคำนวณดอกเบี้ย มีรายละเอียดดังนี้
                        เมท็อดพิเศษหรือคอนสตรักเตอร์นี้ที่มีอาร์กิวเมนต์แบบทูเพิล ซึ่งการเขียนในลักษณะแบบนี้เป็นหลักการของการโอเวอร์โหลด (รายละเอียดเกี่ยวกับการทำโอเวอร์โหลดจะได้กล่าวในหัวข้อต่อไป) ภายในคอนสตรักเตอร์มีเงื่อนไขตรวจสอบจำนวนอาร์กิวเมนต์ ออกเป็น 3 กรณี คือ
                        กรณีที่ 1 เป็นกรณีที่ไม่มีอาร์กิวเมนต์กำหนดให้  balance = 0.0
                        กรณีที่ 2 ถ้ามีอาร์กิวเมนต์จำนวน 1 อาร์กิวเมนต์ กำหนดให้อาร์กิวเมนต์ที่รับเข้ามาเก็บในตัวแปร balance และกำหนดให้ตัวแปร interest_rate เก็บค่า default_interest 
                        กรณีที่ 3 ถ้ามีอาร์กิวเมนต์จำนวน 2 อาร์กิวเมนต์  กำหนดให้อาร์กิวเมนต์ที่ 1รับเข้ามาเก็บในตัวแปร balance และอาร์กิวเมนต์ที่ 2 เก็บในตัวแปร interest_rate 
                        เมท็อดที่ 2 คือ add_monthly_interest() สำหรับคำนวณดอกเบี้ย ดังนั้น จึงเขียนสูตรการคำนวณดอกเบี้ยให้กับเมท็อดนี้ แต่ในกรณีที่ balance เท่ากับ 0 จะทำให้การหารด้วย ตัวตั้งเป็น 0 ทำให้เกิด error จึงเขียนด้วยการสร้างเงื่อนไขป้องกันเอาไว้
                การเรียกใช้คลาสโดยการสร้างอ็อบเจกต์จากคลาสทั้งสองได้ ซึ่งอ็อบเจกต์ที่สร้างขึ้นมาจากคลาสแม่สามารถใช้แอตทริบิวต์และเมท็อดจากคลาสแม่เพียงอย่างเดียวเท่านั้น ต่างจากอ็อบเจกต์ที่สร้างขึ้นมาจากคลาสลูกที่สามารถเรียกใช้ได้ทั้งคลาสแม่และคลาสลูก ดังภาพที่ 9.14

source code

Taweerat = Account(25000)
print "Taweerat มีเงินในบัญชี ",Taweerat.getBalance()
Taweerat.deposit(5000)
print "Taweerat มีเงินในบัญชี ",Taweerat.getBalance()
Taweerat.withdraw(10000)
print "Taweerat มีเงินในบัญชี ",Taweerat.getBalance()
print "-----------------------------------------"

Somchai = InterestAccount(1500,10)
Somchai.deposit(5000)
print "Somchai มีเงินในบัญชี ",Somchai.getBalance()
Somchai.add_monthly_interest()
print "Somchai มีเงินในบัญชี ",Somchai.getBalance()

ภาพที่ 9.14  แสดงคำสั่งการสร้างอ็อบเจกต์และเรียกใช้เมท็อด
จากภาพที่ 9.14 เป็นการเรียกใช้คลาส หรือการเข้าถึงคลาส ด้วยการสร้าง             อ็อบเจกต์ การเรียกใช้เมท็อดหรือฟังก์ชัน จากภาพเป็นการยกตัวอย่างการสร้างอ็อบเจกต์ จำนวน 2 อ็อบเจกต์ ได้แก่ Taweerat และ Somchai โดย Taweerat  สร้างขึ้นจากคลาส Account ที่เป็นคลาสแม่ โดยมีอาร์กิวเมนต์เป็นจำนวนเงินในการเปิดบัญชีครั้งแรก 25,000 บาท จากนั้นใช้คำสั่งให้แสดงผล โดยการเรียกเมท็อด getBalance() และถัดมาได้เรียกใช้เมท็อด deposit(5000) เป็นการฝากเงินเพิ่ม โปรแกรมจะเรียกเมท็อด deposit() และส่งอาร์กิวเมนต์ 5000 ไปบวกเพิ่มกับ balance สุดท้ายมีการเรียกใช้เมท็อด withdraw(10000) เป็นการถอนเงิน โปรแกรมจะไปเรียกเมท็อด withdraw() นำค่าอาร์กิวเมนต์ 10000 ไปลบกับ balance แล้วเก็บในตัวแปร balance
                        ในส่วนของอ็อบเจกต์ Somchai เป็นการสร้างจากคลาส InterestAccount ซึ่งเป็นคลาสลูก โดยมีอาร์กิวเมนต์ 2 ค่า ค่าแรกเป็นจำนวนเงินเปิดบัญชีครั้งแรก อาร์กิวเมนต์ที่ 2 เป็นอัตราดอกเบี้ย มีการเรียกใช้เมท็อด deposit(5000) เป็นการฝากเงินเพิ่ม ให้สังเกตการเรียกใช้เมท็อดจากอ็อบเจกต์ที่สร้างมาจากคลาสลูกสามารถเรียกใช้จากคลาสแม่ได้ทุก ๆ เมท็อดและแอตทริบิวต์ สุดท้ายอ็อบเจกต์ Somchai ได้เรียกใช้เมท็อด add_monthly_interest() สำหรับคำนวณเงินต้นบวกดอกเบี้ย นอกจากนี้ Somchai สามารถสร้างเป็นอ็อบเจกต์แบบอื่น ๆ และใช้เมท็อดที่มีอยู่ในคลาส Account ได้ เช่น

                              Somchai = InterestAccount()
                              Somchai = InterestAccount(5000)
                              Somchai.withdraw(1000)

                        แต่ในทางตรงกันข้ามอ็อบเจกต์ Taweerat ไม่สามารถเรียกใช้แอตทริบิวต์และ  เมท็อดที่สร้างจากคลาส InterestAccount ได้เลย เช่น

                              Taweerat.add_monthly_interest()  

                        ผลการทำงานของโปรแกรม ดังภาพที่ 9.15

output

>>>
Taweerat มีเงินในบัญชี  25000
Taweerat มีเงินในบัญชี  30000
Taweerat มีเงินในบัญชี  20000
-----------------------------------------
เปิดบัญชีได้รับดอกเบี้ยพิเศษ
Somchai มีเงินในบัญชี  6500
Somchai มีเงินในบัญชี  6554.16666667
>>> 

ภาพที่ 9.15  แสดงผลลัพธ์ของการการรับทอด

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

Set MongoDB in the windows path environment

  Let’s set MongoDB in the windows environment in just a few steps. Step 1: First download a suitable MongoDB version according to your mach...