หลายๆคนคงสงสัยว่า Keyword Abstract มัน คือ อะไร และเมื่อไหร่ที่ควรจะใช้ วันนี้ผมมีตัวอย่างง่ายๆในการอธิบายนะครับ โดยอาจจะแทรกเนื้อหาเกี่ยวกับ interface เพิ่มเข้าไปด้วยครับ เพราะลายคนสับสนกันเยอะ โดยผมขอเริ่มโจทย์ที่เราต้องใช้ Abstract Class ดังนี้
จงเขียน class Student ซึ่งประกอบด้วย data members ดังนี้ name (ชื่อนิสิต), test (อะเรย์ของคะแนน), NUM_OF_TESTS (ค่าคงที่เป็นจำนวนของ test) และ courseGrade (เกรดของวิชา) ให้สร้าง Constructor, methods get/set และ abstract method computeCourseGrade โดยมีวิธีการคำนวณต่างกันไปสำหรับนิสิตปริญญาตรี (UndergraduateStudent) และบัณฑิตศึกษา (GraduateStudent)ให้เขียน class UndergraduateStudent ซึ่งเป็น subclass ของ Student และ ทำการ implement method computeCourseGrade ตามเกณฑ์ต่อไปนี้คือ ถ้าคะแนนเฉลี่ย >= 70 ผ่าน (Pass) ถ้าคะแนนเฉลี่ย < 70 ไม่ผ่าน (Fail)ก่อนที่จะทำโจทย์ ผมอยากให้รู้จักคำศัพท์บางตัวก่อน
📌 Signature ของ Method คือ อะไร
การกำหนดลักษณะของ Method name(ชื่อ method) + Parameter List(ตัวแปรที่จะส่งเข้าไป)

📌 Method Header คือ อะไร
พูดง่ายๆ คือ Signature หรือการประกาศ Method ว่ามีซื่ออะไร รับอะไรมาบ้าง ส่วน Logic การทำงานของมันจะไปอยู่ใน Method Detail จ้า ดูตามรูปเลย จะมี pattern ตามนี้ครับ

📌 Interface คือ อะไร
- Interface คือ Class คือ ที่มีข้อมีเฉพาะตัว Method header เท่านั้น ไม่มีการ implement การทำงานอะไรเลย
- Interface ในแง่ของ OOP เป็น Real Abstract อธิบายง่ายๆเลย คือ มันไม่มี Logic การทำงานอะไรเลย มาเป็นกรอบคร่าวๆ
- เวลาสร้าง Class ต้องบอกด้วย keyword interface เสมอ ดังตัวอย่างต่อไปนี้
public interface ListADT{
    //Has only Method Header
    public void insert(Object e) throws Exception;
    public Object retrieve() throws Exception;
}- Class ที่จะเอา interface ไปใช้งานนั้น ต้องใช้ keyword implements เสมอ ดังตัวอย่างต่อไปนี้
public class SimpleList implements ListADT{
    //some code here !!
}📌 Abstract คือ อะไร
- เหมือนกับ Interface แต่จะมีข้อกำหนดที่ยืดหยุ่นกว่า เพราะ เราสามารถที่่ใส่ Logic (เพิ่ม Method และการทำงาน) implement เข้าไปใน Class ที่เป็น abstract ได้
- เวลาสร้าง Class จะต้องบอกไว้ด้วย keyword abstract
- Method ไหนที่ต้องการให้ SubClass เอาไป Implememt ต่อ ต้องมี Keyword abstract ระบุ เพื่อไว้ในส่วนของ Method Modifier เสมอ ดังตัวอย่างต่อไปนี้
public abstract class Student{
    //Has Method Header
    public abstract void computeCourseGrade(); //มีการใส่ Keyword abstract กำกับไว้
    //Implement Method
    public String getCourseGrade(){
	return courseGrade;
    }
}- Class ที่จะเอา abstract ไปใช้งานนั้น จะต้องใช้ keyword extends ดังตัวอย่างต่อไปนี้
public class UndergraduateStudent extends Student {
    //some code here !!
}📌 เมื่อไหรควรใช้ Interface หรือควรใช้ Abstract ?
- ใช้ Interface Class เมื่อต้องการวางกรอบ ขอบเขคร่าวๆ เพื่อใช้ subclass เอาทำ implement การทำงานภายในต่อได้เอง
- ใช้ Abstract Class เมื่อรู้ว่ามีการทำงานบางอย่างที่ ซ้ำๆกันใน subclass โดยยกขึ้นมาเขียนใน Abstract Class เลย และยังเป็นการทำ template ป้องกัน fragment จากการที่ DEV ไป implement กันเอง เพราะต่างคนต่าง Logic แล้วภายหลังจะ maintain ลำบาก- ตัวอย่างการใช้ Abstract Class ถ้าลองจาก Java doc เช่น Abstract Class java.util.AbstractMap ที่รวบรวมการทำงานที่้เหมือนกันของ Subclass ต่างๆ ได้แก่ java.util.EnumMap ,java.util.HashMap ,java.util.LinkedHashMap ,java.util.IdentityHashMap และ java.util.TreeMap โดยสามารถเข้าไปดูใน Javadoc หรือ ดูจากรูปได้ ดังนี้
 

สุดท้ายก่อนจะลง Code ควรวางแผน Design ระบบให้ดีก่อนนะครับ ^___^
เฉลยโจทย์กันก่อน อธิบายยาวจนลืม
- ก่อนอื่นเลยมาดู Diagram แสดงความสัมพันธ์ระหว่าง Class Student ซึ่งเป็น Abstract Class และ Class UndergraduateStudent กับ Class GraduateStudent เป็น SubClass ดังรูป

- มาลองเขียน Class Student ตามที่เงื่อนไขที่โจทย์กำหนดเลยครับ
public abstract class Student{
    protected final static int NUM_OF_TEST = 3;
    protected String name;
    protected String courseGrade;
    public Student(){
        this("No Name");
    }
    public Student(String studentName){
        name = studentName;
        test = new int[NUM_OF_TEST];
        courseGrade = "";
    }
    public abstract void computeCourseGrade();
    public String getCourseGrade(){
        return courseGrade;
    }
    public String getName(){
        return name;
    }
    public int getTestScore(int testNumber){
        return test[testNumber - 1];
    }
    public void setName(String newName){
        name = newName;
    }
    public void setTestScore(int testNumber,int testScore){
        test[testNumber - 1] = testScore;
    }
}- มาลองเขียน Class UndergraduateStudent ตามที่เงื่อนไขที่โจทย์กำหนดเลยครับ
public class UndergraduateStudent extends Student {
    public UndergraduateStudent(){
        super("No Name");
    }
    public void computeCourseGrade(){
        int total = 0;
        for(int i = 0;i < NUM_OF_TEST; i++){
            total += test[i]; 
        } 
        if(total / NUM_OF_TEST >= 70){
            courseGrade = "Pass";
        }else{
            courseGrade = "No Pass";
        }
    }
}- ส่วน Class GraduateStudent ผมจะไม่เฉลยนะครับ ลองไปอ่านดูดีๆ จะพบวา่โจทย์ไม่ได้สั่ง แต่ถ้าผู้อ่านลองเขียนเองสามารถนำ Class UndergraduateStudent ไปประยุกต์ใช้ โดยปรับเปลี่ยนเงื่อนไขให้แตกต่างกัน เช่น ถ้าคะแนนเฉลี่ย >= 90 ผ่าน (Pass) ถ้าคะแนนเฉลี่ย < 90 ไม่ผ่าน (Fail) เป็นต้น
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.



