หลายๆคนคงสงสัยว่า 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 Header คือ อะไร
- 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 หรือ ดูจากรูปได้ ดังนี้
- ตัวอย่างการใช้ 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.