Tutorial

Java 101 – Abstract & Interface (EP.8)

By Arnon Puitrakul - 28 ธันวาคม 2014

Java 101 – Abstract & Interface (EP.8)

เมื่อวานเราได้เรียนเรื่องของ สมบัติหนึ่งของ OOP นั่นคือ Inheritance และ Encapsulation ไปแล้ว วันนี้เราจะมาต่อยอดมันนิดหน่อย นั่นคือเรื่องของ Abstract และ Interface เอาทีละเรื่องล่ะกันเนอะ!
Abstract เป็นหนึ่งในคุณสมบัติของ OOP ที่ให้เราสร้าง Class ที่มี Attribute,Method ขึ้นมาลอยๆเลย ทำอะไรไม่ได้เลย เรื่องนี้มันจะค่อนข้าง งง เอาเรื่องอยู่เหมือนกัน เอาง่ายๆเลยนะครับ ถ้าเราสร้าง Abstract Class ขึ้นมาแปลว่าเราจะนำ Class นี้มาสร้างเป็น Object ไม่ได้ แต่เราสามารถทำให้มันเป็น Class แม่ได้ (หรือนั่นคือสืบทอดได้นั่นเอง) จบนี่คือ Abstract Class ต่อไปเป็นเรื่องของ Syntax
Syntax มันไม่มีอะไรเลย แคเติมคำว่า abstract ไว้หลัง modifier ตอนสร้าง Class เช่น

public abstract class Employee
{
protected String name;
protected String surname;
protected int base_salary;
protected int pos;

Employee ()
{
base_salary = 10000;
}

public double cal_salary ()
{
return base_salary*pos;
}
}

ผมสร้างAbstract Class ที่ชื่อว่า Employee มาเพราะฉะนั้น เราจะไม่สามารถสร้าง Object จาก Class ตัวนี้ได้ ทีนี้เราจะมาสร้าง Class อีกสักอันล่ะกัน ผมให้ชื่อว่า emp_manager

public class emp_manager extends Employee
{
emp_manager ()
{
pos = 3;
name = "Blank";
surname = "Blank";
}

emp_manager (String in_name, String in_surname)
{
pos = 3;
name = in_name;
surname = in_surname;
}

}

จากโค๊ตด้านบนนี้ คือเราสร้าง Class ที่สืบทอดมาจาก Class ที่ชื่อว่า Employee มาซึ่งเป็น Abstract Class จากที่เราเห็นได้ว่า Abstract Class นั้นเราจะไม่สามารถที่จะนำมาสร้างเป็น Object ได้ทันที แต่จะต้องมี Class อะไรสักอย่างมาสืบทอดก่อน ไม่งั้นจะ นำมาสร้างเป็น Object ไม่ได้

ถามว่าแล้วเอามันมาทำอะไรล่ะ?

หลายๆคนอาจจะยังไม่เห็นภาพว่า จริงๆแล้วมันเอามาทำอะไร ผมไม่รู้ว่าคนอื่นเอาไปใช้ทำอะไรกัน แต่ผมนั้นเอามาใช้จัดการ การเข้าถึงของ Class เช่น ผมจะสร้าง Class พันธุ์ของสุนัข เช่น puddle shisu เป็นต้น แต่หมาต่างพันธุ์กันก็ยังเป็นหมาอยู่วันยันค่ำ แต่ผมไม่ต้องการสร้าง Object จาก Class dog ผมเลยกำหนดให้ Class dog เป็น Abstract Class ซะเลย (ป้องกันไว้ก่อน) อะไรทำนองนี้

ถัดไปเป็นเรื่องของ Interface

Interface คืออะไร? -> Interface จริงๆแล้วก็เป็น Class หนึ่งเท่านั้นเองครับ แต่ Class นี้พิเศษนิดหน่อยนั่นคือ Class นี้ Method ทุกอันจะต้องเป็น Abstract Method ทั้งหมด **(เมื่อกี้ไม่ได้พูดถึง จริงๆแค่ใส่คำว่า abstract ไว้หลัง modifier ของ method เท่านั้น) **ที่กำหนดเพียงแค่ว่า เราจะรับค่าเป็นอะไร อะไรบ้าง และคืนค่าเป็นอะไร อะไรบ้าง เท่านั้นเอง จึงเหมือนเป็นข้อตกลงระหว่าง Object เพื่อให้มันคุยกันรู้เรื่องเท่านั้นเอง
อาจจะยังมองไม่เห็นภาพกัน ลองนึกเล่นๆ เรามี Class เครื่องใช้ไฟฟ้าหลายๆอย่างดู ทุกอย่างจะต้องใช้ไฟฟ้าเหมือนกันใช่มั้ยครับ
แต่ๆๆๆ ถ้าเราสังเกตดูครับว่า ปลั๊กของแต่ล่ะที่มันก็ไม่เหมือนกัน เหมือนมันมีข้อกำหนดว่า อันนี้ใช้ได้กับปลั๊กอันนี้ ซึ่งข้อกำหนดเหล่านี้ มันก็คือ Interface นั่นแหละครับ มันมีหน้าที่แค่ว่า ปลั๊กต้องมีลักษณะแบบไหน แต่ก็ไม่ได้บอกว่าเครื่องใช้ไฟฟ้านี้เอาไฟไปใช้ยังไง เช่น เครื่องดูดฝุ่นก็เอาไฟฟ้าไปสร้างลม เตารีดเอาไปสร้างความร้อน Interface มันไม่สนครับ มันบอกแค่ว่าปลั๊กจะต้องเป็น แบบนี้ๆนะ เฉยๆ
ต่อไปเรามาดูวิธีเขียนกันบ้าง ผมจะสร้าง Interface ชื่อ Programmer ขึ้นมา

public interface Programmer
{
public void code ();
public void sleep();
public void die();
}

โค๊ตด้านบนนี้ผมบอกว่า ผมสร้าง interface ชื่อว่า programmer ขึ้นมา แล้วบอกว่า โปรแกรมเมอร์ทำอะไรได้บ้างนั่นคือ โค๊ต,นอน,ตาย แต่ผมไม่ได้บอกว่า
โค๊ต ทำยังไง?
นอน ทำยังไง? นอนที่ไหนยังไง?
หรือ ตาย ตายด้วยอะไร? ตายยังไง? ตกบันไดตาย? หรืออะไร
ถัดมา ผมจะสร้าง Class เพื่อเอามาใช้และ (อันนี้ถ้าเราเปรียบ มันจะเหมือนกับ เราสร้าง Class ของเครื่องใช้ไฟฟ้าที่เราเล่าให้ฟังเมื่อกี้เลย) แต่ๆๆๆ Class ที่สร้างนี้จะต้องเป็น Abstract Class เท่านั้นนะ จะมาสร้าง Class ธรรมดา ไม่ได้เด็ดขาด!!! อย่าลืม!!
เมื่อตอนที่เราเรียนเรื่องการ สืบทอด เราใช้คำว่า extends ใช่มั้ยครับ แต่ถ้าเป็นการเอา interface ไปใช้ เราจะเปลี่ยนจาก extends ไปเป็น implements แล้วตามด้วยชื่อของ interface แทน เช่นๆๆ ผมจะสร้าง Abstract Class ชื่อ Super Programmer ขึ้นมา

public abstract class Super_Programmer implements Programmer
{
public void code ()
{
System.out.println("I'm coding....");
}

public void sleep()
{
System.out.println("I'm sleeping");
}

public void die ()
{
System.out.println("I'm ghost.....");
}
}

จากโค๊ตข้างบน เราก็ต้องเขียน Method ตามที่เรา Implement ไว้ใน Interface เลยใช่มั้ยครับ และที่สำคัญมันต้องเป็น Abstract Class ด้วยจากที่เห็นโค๊ตด้านบน ใน Class Super_Programmer นี้ผมก็บอกว่า Method ที่ผม Implement ไว้ใน Interface มันทำยังไงบ้าง

เมื่อไหร่ที่เราจะต้องใช้ Interface?

ถ้าเราเขียนโปรแกรมเล็กๆใช้อยู่คนเดียว Interface ก็ไม่จำเป็นเลย แต่ถ้าเราเขียนโปรแกรมใหญ่ๆและเขียนกันหลายๆคนแล้วนั้น Interface ถือว่าเป็นสิ่งจำเป็นสิ่งหนึ่งเลยทีเดียว มันช่วยให้การพัฒนาโปรแกรมที่ซับซ้อนทำไปได้อย่างดี มีมาตราฐานเพิ่มขึ้นเพราะเรามี Interface มาช่วยคุมแล้วในส่วนหนึ่ง ทำให้เราเลิกกังวลเรื่องนี้ไปได้เลย เพราะมันถูกฟิคไว้ด้วย Interface ไว้แล้ว

แล้ว Interface มันต่างจาก Abstract Class ยังไง?

  • เรื่องแรกคือเรื่องของ Multiple Inheritance เราสามารถทำให้คลาสเราสืบทอด Class แม่ได้หลายๆตัว (One To Many) ได้ด้วย Interface ซึ่ง Abstract Class ทำไม่ได้
  • Interface เป็นแค่การImplement Method ไว้ล่วงหน้าเท่านั้นไม่สนว่าแต่ล่ะ Method นั้นทำงานยังไง
  • เราจะใช้ Interface ก็เพื่อที่จะจัดกลุ่มคุณสมบัติย่อยๆ ที่มีส่วนที่เหมือนกันใน Class โดยที่ Class เหล่านั้นจะไม่ได้สืบทอดจมาจาก Base Class ตัวเดียวกัน แต่ เราจะใช้ Abstract Class เพื่อสร้างBase Class แทน
  • สุดท้าย ถ้าเราเพิ่ม Method ลงใน Interface เราก็ต้องไปไล่แก้ Method ในทุก Class ที่เราให้มันใช้งาน Interface นั้นทุกตัว แต่ ถ้าเป็น Abstract Class ถ้าเราแก้ ก็ไม่มีปัญหา อยากเพิ่มอยากลด ไม่มีผลอะไรทั้งนั้น
    จบไปแล้วกับเรื่อง Abstract กับ Interface เรื่องนี้เป็นเรื่องที่ค่อนข้างเถียงกันเยอะในหมู่คนเขียน Java เพราะอะไรไม่รู้ แต่ผมว่า ด้วยความที่มันใกล้เคียงกัน อันนี้ก็ขึ้นอยู่กับวิธีของเราแล้วล่ะว่าจะใช้วิธีไหนในการเขียนโปรแกรมออกมา
    อ่ออีกอย่างเรื่องนี้เป็นอีกเรื่องที่ค่อนข้างยากอยู่ เพราะฉะนั้นถ้าใครมีคำถามก็สามารถเมล์มา ไม่ก็เฟสมาก็ได้นะ จะพยายามตอบให้ ถ้ามีเวลา สำหรับวันนี้ไปและบาย~~ (เกือบจะจบแล้วนะ อีก 2 EP เองน้าาา)
    **Source Code : **https://drive.google.com/folderview?id=0BwrPA9Miv4o2cWJnbEppRVhIVWc&usp=sharing

Read Next...

จัดการข้อมูลบน Pandas ยังไงให้เร็ว 1000x ด้วย Vectorisation

จัดการข้อมูลบน Pandas ยังไงให้เร็ว 1000x ด้วย Vectorisation

เวลาเราทำงานกับข้อมูลอย่าง Pandas DataFrame หนึ่งในงานที่เราเขียนลงไปให้มันทำคือ การ Apply Function เข้าไป ถ้าข้อมูลมีขนาดเล็ก มันไม่มีปัญหาเท่าไหร่ แต่ถ้าข้อมูลของเราใหญ่ มันอีกเรื่องเลย ถ้าเราจะเขียนให้เร็วที่สุด เราจะทำได้โดยวิธีใดบ้าง วันนี้เรามาดูกัน...

ปั่นความเร็ว Python Script เกือบ 700 เท่าด้วย JIT บน Numba

ปั่นความเร็ว Python Script เกือบ 700 เท่าด้วย JIT บน Numba

Python เป็นภาษาที่เราใช้งานกันเยอะมาก ๆ เพราะความยืดหยุ่นของมัน แต่ปัญหาของมันก็เกิดจากข้อดีของมันนี่แหละ ทำให้เมื่อเราต้องการ Performance แต่ถ้าเราจะบอกว่า เราสามารถทำได้ดีทั้งคู่เลยละ จะเป็นยังไง เราขอแนะนำ Numba ที่ใช้งาน JIT บอกเลยว่า เร็วขึ้นแบบ 700 เท่าตอนที่ทดลองกันเลย...

Humanise the Number in Python with "Humanize"

Humanise the Number in Python with "Humanize"

หลายวันก่อน เราทำงานแล้วเราต้องการทำงานกับตัวเลขเพื่อให้มันอ่านได้ง่ายขึ้น จะมานั่งเขียนเองก็เสียเวลา เลยไปนั่งหา Library มาใช้ จนไปเจอ Humanize วันนี้เลยจะเอามาเล่าให้อ่านกันว่า มันทำอะไรได้ แล้วมันล่นเวลาการทำงานของเราได้ยังไง...

ทำไม 0.3 + 0.6 ถึงได้ 0.8999999 กับปัญหา Floating Point Approximation

ทำไม 0.3 + 0.6 ถึงได้ 0.8999999 กับปัญหา Floating Point Approximation

การทำงานกับตัวเลขทศนิยมบนคอมพิวเตอร์มันมีความลับซ่อนอยู่ เราอาจจะเคยเจอเคสที่ เอา 0.3 + 0.6 แล้วมันได้ 0.899 ซ้ำไปเรื่อย ๆ ไม่ได้ 0.9 เพราะคอมพิวเตอร์ไม่ได้มองระบบทศนิยมเหมือนกับคนนั่นเอง บางตัวมันไม่สามารถเก็บได้ เลยจำเป็นจะต้องประมาณเอา เราเลยเรียกว่า Floating Point Approximation...