สอบถามเรื่อง OOP หน่อยค่ะ

  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.
  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.

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

เพราะเราจะได้ reuse superclass ครับ อย่างคลาสสองคลาส ที่มีหลาย ๆ อย่างคล้าย ๆ กัน แต่ไม่เหมือนกันเสียทีเดียว ก็เอาที่คล้ายกันมารวมเป็น super class ที่ต่างกัน ก็ไป implement ไว้ที่ subclass โค้ดใน subclass ก็จะสั้นลง

ข้อดีอีกอย่างคือ หากเราต้องการเปลี่ยนแปลงอะไรบางอย่าง เราก็แก้ที่ superclass ทีเดียว มันก็จะส่งผลไปกับทุก subclass ด้วย หากแยกคลาสออกจากกันหมด ก็ต้องตามแก้ไปทุกคลาสครับ

veer's picture

จะได้ไม่ต้องเปลี่ยนชื่อ function (method) มั้ง.

sugree's picture

subclass คือการสืบทอดคุณสมบัติจากคลาสต้นแบบที่มีความสามารถเหมือนกันเพื่อให้ทำงานได้มากขึ้น ดีขึ้น ตรงความต้องการมากขึ้น และโค้ดไม่ซับซ้อนเกินไป

สาเหตุหนึ่งที่เราใช้ subclass ก็เพื่อให้โค้ดสะอาด การทำให้คลาสเดียวทำได้ทุกอย่างใช่ว่าจะทำไม่ได้ มันทำได้และง่ายด้วย (ง่ายตอนเขียนนะ ไม่ใช่ง่ายตอนทดสอบหรือตอนมาแก้) ลองนึกตัวอย่างง่ายๆ จะเขียนโปรแกรมแปลงฟอร์แมตวีดีโอซักอัน เอาแบบง่ายๆ ไม่ซับซ้อน เราจะมีโค้ดให้ทำอยู่ 2 ส่วน ได้แก่ อ่าน (decode) และ เขียน (encode) แต่ก็อย่างว่า มันไม่ได้ง่ายขนาดนั้น เพราะแค่ AVI ก็มีวิธีอ่านเขียนอีกเพียบไม่ว่าจะเป็น divx xvid wmv หรืออื่นๆ อีกมากมาย ยังไม่นับเสียง mp3 mp2 ogg อีกนับไม่ถ้วน ดูแล้วยุ่งเหมือนกัน ถ้าบอกว่าเราอยากทำแค่คลาสเดียวทำได้ทุกอย่าง ซึ่งไม่มีปัญหานะ ทำได้แน่ เราจะได้คลาสทำนองนี้

class Converter:
    def decode_divx(self,input):
        pass
 
    def encode_divx(self,raw,output):
        pass
 
    def convert(self,input,output):
        decode = getattr(self,'decode_'+input.format)
        encode = getattr(self,'encode_'+output.format)
 
        encode(decode(input.read),output.write)

เวลาใช้ก็ if else switch case ในทำนองเดียวกัน ถ้าเขียนแบบ oop แล้วใช้ subclass เราก็ประกาศรอไว้เป็น BaseDecoder กับ BaseEncoder ซึ่งก็จะได้ของแถมเป็นว่าเราสามารถเพิ่มความสามารถพิเศษอื่นๆ ขณะทำงานได้

class BaseDecoder:
    def decode(self,input):
        pass
 
class BaseEncoder:
    def encode(self,raw,output):
        pass
 
class DivXDecoder(BaseDecoder):
    def decode(self,input):
        pass
 
class DivXEncoder(BaseEncoder):
    def encode(self,raw,output):
        pass
 
_decoders = {
    'divx': DivXDecoder,
}
_encoders = {
    'divx': DivXEncoder,
}
 
class Converter:
    def convert(self,input,output):
        decoder = _decoders[input.format]
        encoder = _encoders[output.format]
 
        encoder.encode(decoder.decode(input),output)

หมายเหตุ: อย่าเชื่อมาก ผมไม่ได้เรียนด้านนี้มาโดยตรง

miracle's picture

ขอบคุณทุกท่านที่ช่วยตอบนะคะ ได้ความรู้มากค่ะ

ย้าย Codenone

ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น