09 July 2014

Import Class อย่างไรไม่ให้ซ้ำซ้อนกัน

Updated on

        บทความวันนี้ขอนำเสนอเทคนิคเล็กๆน้อยๆที่ผู้ที่หลงเข้ามาอ่านหลายๆท่านอาจจะติดปัญหานี้กัน ซึ่งเป็นปัญหาที่เจอเมื่อประกาศ Import คลาสตัวหนึ่งแล้ว แต่ทว่าทำไมยังเออเรอร์อยู่ซะงั้น ซึ่งอาจจะมีสาเหตุมาจากว่าชื่อคลาสที่ประกาศไว้ใน Import นั่นไม่ตรงกับที่จะใช้งานก็เป็นได้

        อาจจะฟังดูเข้าใจยากเสียหน่อย ดังนั้นมาดูตัวอย่างจริงๆกันเลยดีกว่า

        สมมติว่าเจ้าของบล็อกสร้าง View ขึ้นมาสองตัวใน Layout ประกอบไปด้วย Check Box กับ Radio Button โดยที่ Radio Button จะขอเรียกรวมๆว่า Radio Group เพราะว่าจะเรียกใช้งานผ่านคลาส Radio Group แทน



        แล้วทีนี้เจ้าของบล็อกต้องการเรียกใช้งานคลาส OnCheckedChangListener เพื่อเอาไว้ตรวจจับเหตุการณ์เมื่อผู้ใช้กด Check Box และ Radio Group ดังนั้นเจ้าของบล็อกก็ประกาศดังนี้เลย


        ขั้นตอนนี้พบกันได้บ่อย คือเจ้าของบล็อกยังไม่ได้ประกาศ Import คลาส OnCheckedChangeListener เข้าไป ดังนั้นจึงเอาเม้าส์วางไว้บนคำนั้นแล้วเลือก Import ซะเลย



        ก็จะมีคำสั่ง Import android.widget.RadioGroup.OnCheckedChangeListener เพิ่มเข้ามา ซึ่งโดยปกติก็น่าจะเสร็จเรียบร้อยแล้วเขียนโค๊ดต่อไปได้เลย แต่ทว่ายังมีเออเรอร์แจ้งอยู่ที่ OnCheckedChangeListener ของ Check Box


        พอเอาเม้าส์ไปวางเพื่อดูเออเรอร์ก็จะขึ้นดังนี้



        มาถึงจุดนี้ถ้าเป็นผู้ที่หลงเข้ามาอ่านไม่รู้อิโหน่อิเหน่อะไรก็คงจะกดเลือกที่ Add unimplemented methods กัน



        โปรแกรมก็จะเพิ่มเมธอดของ OnCheckedChangeListener เข้ามาให้ ซึ่งจะเห็นว่ามีเมธอด onCheckedChanged เพิ่มเข้ามา


        แต่ลืมอะไรไปหรือป่าว? นั่นมันเป็นเมธอดของ Radio Group นะ (ดูจากพารามิเตอร์ในเมธอด)

        ซึ่งนี้ล่ะที่เรียกว่าปัญหาการเรียกใช้งานชื่อคลาสที่ดันเหมือนกัน เพราะว่าคลาสของ Radio Group จะมี OnCheckedChangeListener เป็น Interface อยู่ในคลาส และ Check Box ก็เป็นคลาสที่สืบทอดมาจาก Compound Button ซึ่งมี OnCheckedChangeListener เป็น Interface อยู่ในคลาสด้วยเช่นกัน

        แต่ทั้งสองนี้มีแพคเกจที่ต่างกันนั้นก็คือ

        • Radio Group
                android.widget.RadioGroup.OnCheckedChangeListener

        • Check Box
                android.widget.CompoundButton.OnCheckedChangeListener

        ถ้าลองดูจากตัวอย่างที่เกริ่นมาจะเห็นว่าเจ้าของบล็อกได้เผลอประกาศเรียก OnCheckedChangeListener ของ Radio Group ไปซะแล้ว


        จึงเป็นสาเหตุทำให้ Check Box ไม่สามารถเรียกใช้ OnCheckedChangeListener จากคลาสตัวเองได้ เพราะว่ามีการเรียกจาก Radio Group ไปซะแล้ว


        แล้วจะแก้ปัญหานี้ได้อย่างไรละ?

        วิธีแก้ปัญหานั้นทำได้ไม่ยาก แต่ผู้ที่หลงเข้ามาอ่านหลายๆคนมักจะมองข้ามมันไป นั่นก็คือ เอา Import คลาส OnCheckedChangeListener ออกไปสิ แล้วประกาศคลาสที่ใช้งานไว้ในคำสั่งแทน




        เท่านี้ก็แก้ปัญหาได้แล้ว เพราะว่าคลาสของ Radio Button กับ Check Box ได้ทำการประกาศไว้ข้างบนแล้วนั่นเอง ดังนั้นจึงสามารถเรียกใช้คลาสที่อยู่ข้างในคลาสดังกล่าวได้โดยใช้วิธีนี้


        นอกจากคลาสตัวอย่างนี้มีอย่างอื่นอีกมั้ยที่จะเจอปัญหาแบบนี้ ?

        ที่เจ้าของบล็อกเห็นอยู่บ่อยๆ ก็คงจะเป็นคลาส Media


        ถ้าใช้งานอย่างใดอย่างหนึ่งก็คงไม่มีปัญหาอะไร แต่ทางที่ดีเวลาประกาศควรประกาศที่คลาสหลักแทน (ไม่จำเป็นต้องประกาศทั้งสามตัว เอาเท่าที่ใช้ก็พอ)


        และเวลาเรียกใช้งานก็ใช้คำสั่งดังนี้


     
        เพิ่มเติมเสริมความรู้เล่นๆ

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


        ซึ่งเป็นวิธีการประกาศเรียกใช้คลาสโดยระบุทั้งแพคเกจนั่นเอง ข้อดีคือไม่ต้องประกาศ Import ไว้ข้างบนสุดของโค๊ด ทำให้ผู้ที่มาดูสามารถรู้ได้เลยว่าคลาสตัวนี้มาจากไหน (ก็เล่นระบุยันแพคเกจ) แต่ข้อเสียคือ ทำให้โค๊ดยาวจนเกินจำเป็น


        เรื่องเล็กๆน้อยๆพวกนี้พอลองศึกษาลงไปลึกๆก็สนุกดีเหมือนกันนะเออ