Important Announcement
PubHTML5 Scheduled Server Maintenance on (GMT) Sunday, June 26th, 2:00 am - 8:00 am.
PubHTML5 site will be inoperative during the times indicated!

Home Explore Basic Java

Basic Java

Published by chartsuwun, 2017-04-25 04:13:28

Description: Basic Java

Search

Read the Text Version

บทที่ 5 Objects และ Classes 146เร่มิ ตน กับ Java } //swapping contents of given objects private static void swap(Values pointA, Values pointB) { Values temp = new Values(); temp = pointA; //copy pointA to temp pointA = pointB; //copy pointB to pointA pointB = temp; //copy temp to pointB }}เรากาํ หนดใหก ารสลบั คา ของ object ทงั้ สองเกิดข้ึนภายใน swap() ซึง่ เราคดิ วา นา จะทาํ ได 100% แตหลงั จากท่ี run โปรแกรมดู เรากลบั ไดผลลพั ธด งั น้ี(10, 20)(30, 50)(10, 20)(30, 50)ซึง่ บอกใหเ รารวู า swap() ของเราใชไมไ ด เราตองเปล่ยี นแปลง code ของ swap() ใหมเ พือ่ ใหก ารสลับเกดิ ข้นึ จรงิ และหลังจากท่เี ราเปลีย่ น code ใหเปนprivate static void swap(Values pointA, Values pointB) { Values temp = new Values(); temp.val1 = pointA.val1; temp.val2 = pointA.val2; pointA.val1 = pointB.val1; pointA.val2 = pointB.val2; pointB.val1 = temp.val1; pointB.val2 = temp.val2;}ผลลัพธท เ่ี ราไดคอื(10, 20)(30, 50)(30, 50)(10, 20)ซึ่งแสดงถงึ การสลับคา ที่ไดผ ลจริง สาเหตทุ ี่ swap() ตัวแรกของเราทาํ งานไมไ ด ก็เน่ืองจากวา การเปลย่ี นแปลงคา ของ object เกิดข้ึนจาก copy ของ object ท้งั สองที่มาจาก parameter ไมใชตวั objectจรงิ ๆ ดงั นัน้ การเปลยี่ นแปลงท่ีเกิดขึ้นจึงเกิดขึ้นภายในตัว swap() ไมมผี ลกระทบใด ๆ กบั objectภายนอกเลย เราตอ งทาํ การเปล่ยี นคาใหกับสมาชิกท่ีอยูใน object นัน้ โดยตรงดังเชน ท่ี swap() ตวั ทส่ี องไดแ สดงไวเราไดพ ูดถึง class Student ที่เราสรา งคางไวโดยเราไดสาํ รวจ การสราง method ตา ง ๆ รวมไปถงึ การสงคาเขาสู method ตอนนีเ้ ราจะมาดูถงึ รายละเอียดของ method ตาง ๆ ท่มี อี ยใู น class Student รวมไปถงึโปรแกรมทเี่ รยี กใช object ทเี่ กิดจาก class Studentกอนทเี่ ราจะพดู ถึง method ทม่ี อี ยใู น class Student เรามาดตู วั โปรแกรมท่เี รียกใช method เหลา นี้ดู//TestStudent.java ภาควิชาคอมพิวเตอรธ รุ กจิ วทิ ยาลยั ฟารอ สี เทอรน

บทที่ 5 Objects และ Classes 147เรมิ่ ตน กับ Javaclass TestStudent { public static void main(String[] args) { //create two student objects with given info. Student stu1 = new Student(\"19757\", \"Jim\", \"Jones\", \"02/10/1962\"); Student stu2 = new Student(\"20135\", \"Ray\", \"Smith\", \"12/09/1977\"); //display each student's info. stu1.display(); stu2.display(); //display total number of students System.out.println(\"Total number of objects created: \" + stu1.getCount()); //access field in class via object String date = stu1.dateOfBirth; System.out.println(\"Date of birth of stu1 is \" + date); }}เราไดสราง object stu1 และ stu2 จาก class Student ดว ยขอ มลู ดงั ที่เหน็Student stu1 = new Student(\"19757\", \"Jim\", \"Jones\", \"02/10/1962\")Student stu2 = new Student(\"20135\", \"Ray\", \"Smith\", \"12/09/1977\")หลังจากนัน้ เรากเ็ รียกใช method display() ในการแสดงผลขอมูลของ object ทัง้ สองตัว โดยทีเ่ ราไดออกแบบ method display() ของเราใหมกี ารเรียกใช method อื่น ๆ ทมี่ ีอยูใน class Student ดังน้ีpublic void display() { System.out.print(getId() + \" \"); System.out.print(getFirstName() + \" \"); System.out.print(getLastName() + \" \"); System.out.println(\"Age: \" + getAge()); return ;}ผูอ า นจะสังเกตไดวา เราเรยี ก method getId() getFirstName() getLastName() และ methodgetAge() ภายในประโยคของ System.out.println(…) ซ่ึง method เหลาน้จี ะสงคาของ field ตาง ๆ ที่ไดถ กู กําหนดไวใ หก บั ประโยคในการแสดงขอมูลไปยงั หนา จอหลงั จากท่ีขอ มูลของ object ทงั้ สองตวั ไดถ กู แสดงไปยังหนาจอแลว เรากเ็ รียกประโยคSystem.out.println(\"Total number of objects created: \" + stu1.getCount());String date = stu1.dateOfBirth;System.out.println(\"Date of birth of stu1 is \" + date);สาํ หรบั การแสดงจํานวนของ object ท่ไี ดถ ูกสรางขนึ้ ทั้งหมด และวนั เดอื น ป เกดิ ของ object ทช่ี ื่อ stu1ไปยังหนา จอ และผลลพั ธของการ run ทไ่ี ดค อื19757 Jim Jones Age: 4120135 Ray Smith Age: 26Total number of objects created: 2Date of birth of stu1 is 02/10/1962 ภาควิชาคอมพิวเตอรธุรกิจ วิทยาลยั ฟารอสี เทอรน

บทที่ 5 Objects และ Classes 148เรมิ่ ตน กับ Javaผูอานตองกาํ หนดใหก ารเรียก method ที่มอี ยูใ น class ผานทาง object ท่ีไดส รา งขึ้น ดวยการใช . (dot)ตามดวยชอ่ื ของ method ทีต่ อ งการเรยี กใช เชนstu1.display();เชน เดียวกนั กบั การเรียกใช data member เรากต็ องขนึ้ ตน ดว ยชื่อของ object ตามดวย . (dot) ตามดว ยตวั แปรทตี่ องการใช เชนstu1.dateOfBirth;เน่อื งจากวา เราไมไดก าํ หนดนโยบายการเขา หา ตวั แปร หรอื method ท่มี อี ยใู น class ดังนั้นการเขาหาจงึไมขอ กําหนดใด ๆ เราสามารถทจี่ ะเขาหาขอมูลทกุ ตวั โดยไมม ีขอ จาํ กดั กอนที่เราจะพดู ถงึ นโยบายการเขาหาขอ มูลทอ่ี ยูใน class เราอยากที่จะพูดถึง method getAge() ท่ีมีอยูใ น class Student สักเลก็ นอ ยmethod getAge() ไดถกู ออกแบบใหท าํ การคํานวณหาอายุดวยการหาจากการลบปเ กดิ ออกจากปปจ จบุ ัน ดงั น้นั เราจึงตอ งเรยี กใช method จาก class Calendar ในการคาํ นวณหาปปจ จุบัน ดังนี้public int getAge() { //retrieve a year String year = dateOfBirth.substring(6); //convert it to an int int birthYear = Integer.parseInt(year); //get current year from system's calendar Calendar now = Calendar.getInstance(); int thisYear = now.get(Calendar.YEAR); //return the difference return thisYear - birthYear;}กอนทเี่ ราจะคํานวณหาอายไุ ด เราตองดึงเอา field ท่เี ปน ปเกดิ ทอ่ี ยใู นรูปแบบของ dd/mm/yyyy ออกมากอนดว ยการใช method substring() ที่เราไดพ ูดไวก อ นหนา นี้ เมอื่ ไดแ ลวเราก็เปลีย่ น string ทีม่ ีคาเปนปเกดิ นีใ้ หเ ปน int ดวยการเรยี กใช Integer.parseInt()หลงั จากนน้ั เราก็ดึงเอาปป จจุบนั ออกจากเคร่อื งดวยคาํ สัง่Calendar now = Calendar.getInstance();int thisYear = now.get(Calendar.YEAR);ซ่ึงกอนท่เี ราจะดงึ ปออกไดเ ราตอ งสรา ง instance จาก class Calendar กอ นและเมื่อไดแ ลว เรากใ็ ชmethod get() ในการดึงเอาปป จ จบุ นั ออกมา กระบวนการที่เหลืออยกู ค็ ือการสง สว นตางระหวา งปป จ จุบันกับปเกดิ ออกไปยงั ผทู ีเ่ รยี กใช method นี้ (การดึงเอาคา ของปอ อก ผูอา นตอ งระวงั ในเรือ่ งของปท ่ีใชใ นเครอ่ื ง ณ เวลานัน้ ดวยวา อยูในรูปแบบของ พุทธศักราช หรอื ครสิ ตศักราช Windows ใหม ๆ ยอมใหมีการตง้ั คา ตามตาํ แหนงทตี่ ้งั ของประเทศน้นั ๆ)การสราง class Student ของเรานั้นเราไมไดก าํ หนดนโยบายการเขา หา field หรอื method ตา ง ๆ ของเราอยางไรเลย ผูอา นคงสังเกตเห็นวา ตัวแปรทุกตวั ของเราไมมคี ําใด ๆ นําหนา เลย เชน private publicหรอื แมก ระทั่งคาํ วา protected หวั ขอตอไปจะพดู ถงึ เรอ่ื งของการกําหนดนโยบายการเขา หาตัวแปร และmethod ของ class วาจะมีประโยชนอ ยา งไรในการออกแบบ class (ผอู า นลองตัง้ คาํ ถามใหต วั เองกอ นเร่มิ หัวขอถัดไปวา ถาใสค าํ วา private หนาตวั แปรทุกตัวจะมีผลตอโปรแกรม TestStudent.java อยางไรถาใสหนา method ตา ง ๆ หละ?) ภาควิชาคอมพิวเตอรธรุ กจิ วิทยาลยั ฟารอ สี เทอรน

บทท่ี 5 Objects และ Classes 149เรม่ิ ตนกบั Javaการกาํ หนดนโยบายในการเขา หาสมาชกิ ของ class (attributes)จาก class Circle ของเราทไี่ ดส รา งขนึ้ ในการประกาศตัวแปร radius นัน้ เราไดก าํ หนดใหม คี ําวา privateอยูดา นหนา ของตัวแปร ดงั นี้private double radius;ทาํ ไมเราถึงทาํ เชน น้ี?สาเหตทุ ่เี ราทําเชนนก้ี ็เพือ่ ท่ีจะกําหนดการเขา หาตวั แปรตวั น้ี โดยท่วั ไปแลว ถา เราไมใ สค าํ วา private ไวหนาตวั แปรใด เราก็สามารถทจี่ ะเขา หาตวั แปรตวั นี้ ผานทางโปรแกรมอน่ื ๆ ท่ีเรยี กใช class Circle การกาํ หนดนโยบายของการเขา หานนั้ เราสามารถทาํ ไดสวี่ ิธี คอื1. ไมใ ชค ําใด ๆ นาํ หนาตวั แปร (friendly)2. ใชคาํ วา private นาํ หนา ตวั แปร (not too friendly)3. ใชค าํ วา public นําหนาตวั แปร (friendly)4. ใชค าํ วา protected นาํ หนาตวั แปร (somewhat friendly)ถา เราไมใชคาํ ใด ๆ นาํ หนา ตวั แปรการเขาหาตวั แปรตวั นจี้ ะทําไดเฉพาะ class ทอ่ี ยูภายในพื้นทีเ่ ดยี วกนัเชนภายใน class เดียวกนั หรอื ภายใน package (ดเู รอื่ งการสรางและใช package ทา ยบท) เดยี วกัน ดงัโปรแกรมตวั อยา งที่แสดงใหด นู ้ี//Access.javaclass Dot { //no access control String name; int value; Dot(String s, int v) { name = s; value = v; }}class Access { public static void main(String[] args) { Dot myDot = new Dot(\"I am a dot.\", 10); //access both name and value fields from class Dot System.out.println(\"Name is \" + myDot.name); System.out.println(\"Value is \" + myDot.value); }}เมือ่ เรา run ดูผลลพั ธท ี่ไดค ือName is I am a dot.Value is 10โปรแกรม Access.java สามารถทจี่ ะเขา หา field ท้งั สองที่เราสรา งข้นึ ใน class Dot ของเราผา นทางobject ช่อื myDot (หมายความวา ใคร ๆ ก็เขา หาตัวแปรของเราไดถ า เขารูวา เรามตี วั แปรอะไรบา ง –อันตราย?)ทีน้เี ราลองนาํ เอาคาํ วา private ไปใสไวห นา ตวั แปรทง้ั สองของเรา ดงั น้ีprivate String name; ภาควิชาคอมพิวเตอรธุรกจิ วิทยาลัยฟารอีสเทอรน

บทท่ี 5 Objects และ Classes 150เรมิ่ ตน กับ Javaprivate int value;การ compile โปรแกรมอีกครั้งหนึ่งจะทําใหเกดิ error ดงั นี้Access.java:20: name has private access in Dot System.out.println(\"Name is \" + myDot.name); ^Access.java:21: value has private access in Dot System.out.println(\"Value is \" + myDot.value); ^2 errorsเราไมส ามารถทีจ่ ะอางถงึ ตัวแปรท้งั สองไดเ พราะคาํ วา private เราตอ งเขา หาดวยวธิ อี ื่น เชน เขียนmethod ท่ีสงคา ของตวั แปรทง้ั สองกลับ (โดยเขียนไวใ น class Dot) เหมือนกบั ที่เราไดท าํ ไวใน classCircleเรากาํ หนดใหตวั แปร radius ของ class Circle เปน private data member ดังนน้ั เราจึงตอ งเขยี นmethod ในการเขา หาตัวแปร radius ของเรา ดงั นี้public double getRadius() { return radius;}เพราะฉะนนั้ ถาเราไมตอ งการใหโปรแกรม หรอื ผูใด (object) เขา หาตวั แปรของเรา เราก็นาํ คาํ วา privateไปแปะไวด า นหนา ของตัวแปรน้ัน ๆ ถา สงั เกตใหด ีจะเหน็ วา method changeRadius() ใน class Circle ก็มีคาํ วา private อยูดา นหนาเหมือนกนั ท้งั น้กี ็เพราะวา เราไมต อ งการใหใครเขา หา method ตัวนยี้ กเวนmethod ทีอ่ ยภู ายใน class เดียวกัน การเขา หา method นผี้ านโปรแกรม หรอื object ตัวอน่ื จะทาํ ไมไ ดและ Java compiler จะฟอ งดว ย error ทันทีเราจะกลับมาดคู าํ วา protected ในโอกาสตอ ไป ทงั้ นี้เพราะคาํ ๆ นม้ี ีเงือ่ นไขซบั ซอ นอยูพ อสมควร สําหรบัคําวา public น้ันจะยอมใหท ุกโปรแกรม หรือ object เขาหาตัวแปร หรือ method ไดโ ดยไมม ีเง่ือนไขใดๆ ท้ังส้ินการกําหนดนโยบายการเขาหาตัวแปรหรอื method ทําใหก ารควบคมุ โปรแกรมทําไดดยี ิ่งข้นึ อะไรทผี่ ูใ ชไมควรรูไมค วรเห็น เราก็ซอนสงิ่ เหลานไี้ ว การกระทาํ ในลกั ษณะนเ้ี ราเรยี กวา encapsulation ซงึ่ เปนหนึง่ในขอกําหนดของการออกแบบและเขยี นโปรแกรมในรูปแบบของ OOP ในสวนตวั ของผูเ ขียนแลว ชอบที่จะใช private กบั ตัวแปรทกุ ตวั และ method บางตวั ท่ีไมม ีการเขา หาจากภายนอก เพราะจะทําใหก ารใชตวั แปรมีขอจํากดั สว นทเ่ี ขา หาขอมลู เหลา นข้ี องเราไดเ ปนไดเฉพาะ method ท่เี ราไดก ําหนดไวเทานัน้Constructor อกี ครงั้Constructor มีไวส ําหรบั การกาํ หนดคา เบอ้ื งตนใหก ับตวั แปรท่ีอยใู น class และการเรียกใช constructorนน้ั เราไมต อ งทาํ โดยตรง constructor จะถกู เรยี กโดยอัตโนมตั ผิ า นทางการสรา ง object จาก class ดังที่ไดแ สดงไวใ นโปแกรมทส่ี ราง object จาก class Circle จากประโยคของการสรา งวงกลมทว่ี าCircle red = new Circle(5.0);ขั้นตอนท่เี กิดขนึ้ เม่ือประโยคนถ้ี ูก execute คอืConstructor ของ Circle ถกู เรยี กดว ยคา 5.0 ซ่ึงหมายความวาตัวแปร radius ท่อี ยูใน class Circle จะไดรบั คา ท่กี ําหนดให คอื 5.0 หลงั จากน้ันตาํ แหนง หรือ address ของ object ทถ่ี ูกสรางและกําหนดคาน้ีจะถูกเกบ็ ไวใ น red เพื่อใหเหน็ ภาพชดั ขน้ึ เราจะเพิม่ ประโยคดา นลางน้ีเขากบั constructor ของ classCircleSystem.out.println(\"Constructor activated with parameter value of \" + radius); ภาควิชาคอมพิวเตอรธ ุรกิจ วทิ ยาลยั ฟารอสี เทอรน

บทท่ี 5 Objects และ Classes 151เริม่ ตน กับ Javaเพราะฉะนน้ั constructor ของ class Circle ก็จะเปนCircle(double r) { radius = r; System.out.println(\"Constructor activated with value of \" + radius);}และเราจะลองสราง object สองตัวจาก class Circle ดงั นี้class PassByReference { public static void main(String[] args) { Circle red = new Circle(5.0); Circle blue = new Circle(3.5);}หลังจากท่ี compile และ run ผลลพั ธท ไ่ี ดค อืConstructor activated with value of 5.0Constructor activated with value of 3.5เราจะเห็นวา object สองตวั ถกู สรา งดวย radius ท่ีตางกัน คอื 5.0 และ 3.5 และทงั้ ๆ ทไ่ี มม ปี ระโยคของการแสดงผลใน method main() ใด ๆ เลย เรากลับไดผ ลลพั ธด ังท่เี หน็ ท้ังนก้ี ็เพราะวา constructor ของเราทมี่ ีอยใู น class Circle ไดรับการเรียกใชโดยอตั โนมตั ิเราสามารถทจ่ี ะสรา ง constructor ใหกบั class ไดม ากกวาหนึง่ ตวั ทั้งนี้การกระทาํ ดงั กลา วจะตอ งอยูภายใตเ งอ่ื นไขที่ Java กําหนดไว คือ parameter ทีส่ ง ไปยงั constructor ตองไมม จี าํ นวนทเี่ ทา กนั และถาจํานวนของ parameter เทากัน ชนิดของ parameter ตอ งไมเหมือนกนั (หนังสอื เกือบทกุ เลม เรียกขนั้ ตอนนี้วาการกําหนด signature) ลองดโู ปรแกรมตัวอยาง//TestMean.javaclass Mean { private double x, y, z; //constructor with one value Mean(double value) { x = value; y = 0.0; z = 0.0; } //constructor with two values Mean(double value1, double value2) { x = value1; y = value2; z = 0.0; } //constructor with three values Mean(double value1, double value2, double value3) { x = value1; y = value2; z = value3; } ภาควิชาคอมพิวเตอรธรุ กจิ วทิ ยาลยั ฟารอีสเทอรน

บทท่ี 5 Objects และ Classes 152เริ่มตน กับ Java public double findMean() { return (x + y + z) / 3; }}class Mean ของเรามี constructor อยูส ามตวั โดยทต่ี ัวแรกมี parameter หนึง่ ตวั constructor ตวั ทสี่ องมี parameter สองตวั และ constructor ตัวทส่ี ามมี parameter สามตวั ภายใน class เราไดสรา งmethod findMean() สําหรบั การคํานวณหาคา เฉล่ยี ของตวั แปรท้ังสามของ class และเราไดเขยี นโปรแกรมสําหรบั ตรวจสอบการใช constructor ดังกลาวดงั นี้class TestMean { public static void main(String[] args) { //create objects with diferent parameters Mean m = new Mean(12.0); Mean n = new Mean(10.0, 20.0); Mean p = new Mean(10.0, 20.0, 30.0); System.out.println(\"Mean of m is \" + m.findMean()); System.out.println(\"Mean of n is \" + n.findMean()); System.out.println(\"Mean of p is \" + p.findMean()); }}โปรแกรม TestMean.java ประกาศใช object จาก class Mean สามตัวดว ยจาํ นวนของ parameter ที่ตา งกัน คอื หนง่ึ ตัว สองตวั และสามตัวตามลําดบั หลงั จากทีเ่ ราเรยี ก method findMean() สาํ หรับobject ทัง้ สามตวั แลว ผลลัพธทีเ่ ราไดจ ากการ run คือMean of m is 4.0Mean of n is 10.0Mean of p is 20.0จะเห็นวา Java เลือกใช constructor ไดถ กู ตองตามการออกแบบทีเ่ รากาํ หนดไว ซงึ่ วิธกี ารแบบนเี้ ราเรยี กวา constructor overloading เรามาลองดกู าร overload ของ constructor ทีม่ จี ํานวนของparameter เหมอื นกนั แตตางชนิดกันดู อกี สกั ตวั อยา งหน่งึ//TestMean1.javaclass Mean { private double x, y, z; //constructor with three values Mean(double value1, double value2, double value3 { x = value1; y = value2; z = value3; } //constructor with three values (different type) Mean(double value1, int value2, String value3) { x = value1; y = (double)value2; z = Double.parseDouble(value3); } public double findMean() { return (x + y + z) / 3; }} ภาควิชาคอมพิวเตอรธรุ กจิ วทิ ยาลยั ฟารอีสเทอรน

บทที่ 5 Objects และ Classes 153เรม่ิ ตนกับ Javaclass Mean ของเรากาํ หนดใหม ี constructor สองตัว โดยกาํ หนดใหต ัวแรกรบั parameter ท่ีเปนdouble ทงั้ สามตวั สว น constructor ตัวทส่ี องรับ parameter ทีเ่ ปน double int และ String ตามลาํ ดบัซง่ึ เราไดเ ปล่ยี นคาทไี่ มใ ช double ของทัง้ สอง parameter ใหเ ปน double ภายในตวั constructor เองclass TestMean1 { public static void main(String[] args) { //create objects with diferent parameters Mean p = new Mean(10.0, 20.0, 30.0); Mean q = new Mean(10.0, 20, \"40.0\"); System.out.println(\"Mean of p is \" + p.findMean()); System.out.println(\"Mean of q is \" + q.findMean()); }}โปรแกรม TestMean1.java ประกาศการใช object สองตวั คอื p และ q จาก class Mean ดว ยparameter ตา งกันดังท่ีเหน็ ผลลพั ธทีไ่ ดข องการ run คอืMean of p is 20.0Mean of q is 23.0333333333333332เชน เดยี วกับโปรแกรมกอนหนา นี้ ผลลพั ธท ไ่ี ดแสดงถงึ การเรียกใช constructor ท่ีถูกตองของ Javaยังมีวิธอี ื่นทเ่ี ราสามารถทจ่ี ะ overload constructor ได วิธีน้ีเราจะเรยี ก constructor ตัวอน่ื จากconstructor อกี ตวัการเรียก constructor จาก constructorวิธกี ารเรยี ก constructor จาก constructor ก็ไมย าก เราเพยี งแตกาํ หนดวธิ ีการเรียกใหเหมาะสม ซ่ึงJava ยอมใหมกี ารเรยี ก constructor จาก constructor ผา นทางคาํ วา this ดังตวั อยา งท่ไี ดแ สดง ดงั นี้//TestMean2.javaclass Mean { private double x, y, z; //constructor with one value Mean(double value) { x = value; y = 0.0; z = 0.0; } //constructor with two values Mean(double value1, double value2) { //calling constructor with one argument this(value1); y = value2; } //constructor with three values Mean(double value1, double value2, double value3) { //calling constructor with two arguments this(value1, value2); z = value3; } ภาควิชาคอมพิวเตอรธ รุ กิจ วิทยาลยั ฟารอ สี เทอรน

บทท่ี 5 Objects และ Classes 154เร่มิ ตนกับ Java public double findMean() { return (x + y + z) / 3; }}class TestMean2 { public static void main(String[] args) { //create objects with diferent parameters Mean m = new Mean(12.0); Mean n = new Mean(10.0, 20.0); Mean p = new Mean(10.0, 20.0, 30.0); System.out.println(\"Mean of m is \" + m.findMean()); System.out.println(\"Mean of n is \" + n.findMean()); System.out.println(\"Mean of p is \" + p.findMean()); }}เราไดด ดั แปลงโปรแกรมของการหาคา เฉลย่ี ของเลขสามตัวกอ นหนา นใี้ ห มี constructor ทเี่ รยี กใชconstructor ดงั นี้Mean(double value) { x = value; y = 0.0; z = 0.0;}Mean(double value1, double value2) { //calling constructor with one argument this(value1); y = value2;}Mean(double value1, double value2, double value3) { //calling constructor with two arguments this(value1, value2); z = value3;}constructor ตวั แรกกาํ หนดคา ใหกบั ตัวแปรเชนเดียวกับทไี่ ดทาํ ไวก อนหนา น้ี สวน constructor ตัวทสี่ องและสามเรยี กใช constructor ทม่ี อี ยภู ายใน class Mean ดว ยการเรยี กผา น this() โดยที่ constructor ตัวทีส่ องเรยี ก constructor ตวั แรกดวยคําสง่ั this(value1) เมื่อ Java เหน็ การเรยี กเชน นี้ ก็จะไปหาconstructor ทม่ี อี ยใู น class วา มตี ัวไหนบางท่มี ีเงื่อนไขตามท่ถี ูกเรยี ก ซงึ่ ก็เปน ไปตามน้ันคือ Java ไปเรียก constructor ทีม่ ี parameter เพียงตวั เดยี วมาทําการกาํ หนดคาเบอื้ งตน ใหกับ object ที่ executeconstructor ตวั นี้ คอื x จะมคี า เปน value1 y และ z จะมีคา เปน 0.0 จากการกําหนด หลงั จากนนั้ การกาํ หนดคา ให y เปน value2 ก็ไดถูกกระทําภายใน constructor ตวั ทสี่ องconstructor ตวั ทส่ี ามก็เชน เดยี วกัน การเรยี ก constructor ทม่ี ี parameter 2 ตวั ก็เกิดข้นึ กระบวนการเดิมทไี่ ดกลา วไวกอนหนา นี้กไ็ ดถูกกระทําขน้ึ เมือ่ ทาํ เสรจ็ แลว การกาํ หนดคา ใหกับตัวแปร z จงึ มขี ึ้น(ผลลัพธของโปรแกรม TestMean2.java กเ็ หมอื นกบั ท่เี ราไดก อนหนาน้)ีการเรยี กใช constructor ทีม่ อี ยแู ลว ทาํ ใหก ารเขียน code ที่ซาํ้ ซอนลดลง การเขียนโปรแกรมก็มีประสทิ ธภิ าพมากข้ึน ภาควิชาคอมพิวเตอรธรุ กิจ วิทยาลัยฟารอ ีสเทอรน

บทท่ี 5 Objects และ Classes 155เร่มิ ตน กับ Javaการ overload methodเน่อื งจากวา constructor ก็เปน method ชนิดหนงึ่ ดงั น้นั ถา เราสามารถทีจ่ ะ overload constructor ไดเรากส็ ามารถทจ่ี ะ overload method ไดเ ชนกัน เพราะฉะนัน้ เราจะมาดเู รอ่ื งการ overload method ซ่งึ ก็ไมแ ตกตางจากการ overload constructor เทา ใดนกั เรามาเริ่มตนดวย method ทีแ่ สดงผลออกทางหนา จอ จากตวั แปรชนดิ ตา ง ๆ ทส่ี งเขา ไปยัง method นี้//Overload.javaclass Ball { private double x, y, z;//constructorBall() { x = y = z = 0.0;} //display coordinates public void display() { System.out.println(\"(\" + x + \", \" + y + \", \" + z + \")\"); }}class Overload {public static void main(String[] args) { Ball ball = new Ball(); //create object display(25); //display int display(350.0); //display double display(\"I love overloading.\"); //display string display('A'); //display char display(ball); //display object}//accept int as a parameterpublic static void display(int data) { System.out.println(data);}//accept double as a parameterpublic static void display(double data) { System.out.println(data);}//accept string as a parameterpublic static void display(String data) { System.out.println(data);}//accept char as a parameterpublic static void display(char data) { System.out.println(data);}//accept object as a parameterpublic static void display(Ball blue) { blue.display(); //calling display() from class Ball} ภาควิชาคอมพิวเตอรธ ุรกิจ วิทยาลัยฟารอสี เทอรน

บทท่ี 5 Objects และ Classes 156เริ่มตนกบั Java}โปรแกรม Overload.java สรา ง method display() เพ่ือรองรบั parameter ตาง ๆ จาํ นวน 5 ตัว คือ รับint รับ double รับ string รบั char และรบั object และกเ็ ชน เดยี วกับการ overload constructor methodทเ่ี ราเขียนข้นึ ตา งก็มี signature ที่ไมเหมอื นกนั ดงั นั้น java ก็สามารถหา method ทถี่ ูกตอ งตามการเรียกใช ผลลัพธท่ไี ดจ ากการ run โปรแกรมคอื25350.0I love overloading.A(0.0, 0.0, 0.0)การใช overload นัน้ มีขอ ดีในการเขยี นโปรแกรมคอื เราไมจ าํ เปน ตอ งหาชอ่ื อืน่ ๆ ทีเ่ หมาะสมกับหนา ท่ีของ method นนั้ ๆ นอกเหนือจากท่เี ราไดเลอื กไวแลว และการใชชื่อเดยี วเพอื่ รองรบั parameter หลายตวั ทาํ ใหผ ใู ชไ มต อ งคนหา method ตัวอ่นื ท่ีทาํ หนา ท่แี บบเดยี วกนั ตัว Java เองก็ไดส รา ง method ไวมากมายที่มกี ารใช overload ในการสรางเพอื่ รองรบั การใชง านของ user ทม่ี ีความหลากหลายของขอ มลูที่สง เขา ไปยัง method นัน้ ๆ ทาํ ใหผใู ชไมต อ งเสยี เวลาในการคน หา method ทต่ี ัวเองตอ งการใชผูอา นควรฝกการเขยี นโปรแกรมดว ยการใช overload method เพ่อื ใหเ กิดความชาํ นาญ และเขาใจถึงวิธกี ารของ method overload มากยงิ่ ข้ึนการสรา ง class ภายใน class (nested class)ตวั อยางของการสรา งและเรยี กใช class ทเ่ี ราไดทราบถึงกอ นหนา นี้ เปน การสรา ง class ทม่ี เี พียงเฉพาะตวั แปร และ method อยภู ายใน class เทานน้ั ยงั ไมมขี อ มูลภายใน class ที่ตัวมนั เองกเ็ ปน classเชน เดียวกัน เราจะมาดูถงึ วิธีการสราง class ภายใน class อยางงาย ๆ เพ่ือใหไ ดร บั ทราบวา Java ยอมใหมีการสราง class ภายใน class เชน เดียวกันกบั ทเี่ ราสามารถสราง method อื่น ๆเราจะลองเขยี นโปรแกรมตวั อยา งแบบงา ย ๆ ที่ class ซอ นกันอยู//NestedClass.javaclass Parent { //create a Child object private String name; Child c = new Child(\"Galvin\"); Parent(String n) { name = n; } public void showName() { System.out.println(\"Parent: \" + name); c.showName(); //calling Child's showName() } class Child { private String name; //create a GrandChild object GrandChild gc = new GrandChild(\"Jeff\"); Child(String n) { name = n; } public void showName() { System.out.println(\"Child: \" + name); gc.showName(); //calling GrandChild's showName() ภาควิชาคอมพิวเตอรธรุ กิจ วิทยาลัยฟารอสี เทอรน

บทท่ี 5 Objects และ Classes 157เริ่มตนกับ Java } class GrandChild { private String name; GrandChild(String n) { name = n; } public void showName() { System.out.println(\"GrandChild: \" + name); } }//class GrandChild }//class Child}//class Parentclass NestedClass { public static void main(String[] args) { Parent p = new Parent(\"Rebecca\"); p.showName(); }}โปรแกรม NestedClass.java สราง object จาก class Parent หนึ่งตวั แสดงขอมลู ทอี่ ยใู น class ผานทาง method showName() ซ่งึ ใหผ ลลพั ธ ดงั น้ี คือParent: RebeccaChild: GalvinGrandChild: Jeffclass Parent ของเราไดสรา ง class อีก class หน่ึงทอ่ี ยูภายในชอื่ Child และ class Child ก็ไดสรางclass อกี class หน่ึงช่ือ GrandChild โดยทกุ class จะมี method ชือ่ showName() ซง่ึ เอาไวใชในการแสดงคาของตวั แปรของแตละ class ไปยงั หนาจอ เราไดส รา ง object จาก class Child ภายใน classParent ช่ือ c และเราเรยี ก method showName() ของ class Child จาก method showName() ของclass Parent ในทํานองเดียวกันร าก็ไดส รา ง object จาก class GrandChild ภายใน class Child และก็เรียก method showName() ของ class GrandChild จาก method showName() ของ class Childดว ย เพราะฉะนนั้ ขัน้ ตอนของการ execute คอืParent.showName() Æ Child.showName() Æ GrandChild.showName()เราสามารถทจ่ี ะสรา ง object จาก class ทอ่ี ยูดา นในผานทาง object ท่ีอยูดา นนอก ดงั เชนตวั อยา งนี้class NestedClass { public static void main(String[] args) { Parent p = new Parent(\"Rebecca\"); p.showName(); Parent.Child newChild = p.new Child(\"John\"); Parent.Child.GrandChild newGrandChild = newChild.new GrandChild(\"Jen\"); newChild.showName(); newGrandChild.showName(); }} ภาควิชาคอมพิวเตอรธ รุ กจิ วทิ ยาลัยฟารอ ีสเทอรน

บทท่ี 5 Objects และ Classes 158เรม่ิ ตน กบั Javaเราเพ่มิ ประโยคใหมเ ขา กบั class NestedClass ของเราเพ่อื แสดงการสรา ง object จาก class ทอ่ี ยูภ ายในประโยคParent.Child newChild = p.new Child(\"John\");สรา ง object จาก class Child ผา นทาง object ทมี่ าจาก class Parent ดว ยการเรียกใช p.newChild(\"John\") เราตองทําการสรา งผา นทาง object ของ class Parent เทาน้นั เราไมส ามารถทจี่ ะสรา งobject จาก class Child ผานทาง class Parent โดยตรง เชน ประโยคParent.Child newChild = Parent.new Child(\"John\");จะไมไดร ับการ compile และ Java จะฟองดว ย error ทันทีการสราง object จาก class GrandChild ผา นทาง class ท่ีอยภู ายนอกทงั้ สองกค็ ลาย ๆ กันผลลัพธของการ run โปรแกรมทถี่ กู ดัดแปลงแลว คือParent: RebeccaChild: GalvinGrandChild: JeffChild: JohnGrandChild: JeffGrandChild: Jenเนอื่ งจากวา เราสรา ง object ของ class Child ผานทาง class Parent ดงั นน้ั เมอื่ เรียกใช methodshowName() เราจงึ ไดผ ลลพั ธChild: JohnGrandChild: Jeffอีกครง้ั หน่งึ สว น object ทส่ี รา งขึ้นใหมจ าก class GrandChild เมื่อเรียก method showName() เราจงึไดเ พียงแต GrandChild: Jen เทาน้ันตัวอยางโปรแกรมการสรา ง nested class ทเ่ี หน็ เปนเพยี งแคตวั อยา งทแี่ สดงใหด ถู งึ การสรา ง nestedclass เทา น้นั การออกแบบ nested class ตองคาํ นึงถงึ ความสมั พันธข องทงั้ class ที่อยดู า นนอก และclass ที่อยดู านในวามีความสมั พนั ธกนั อยางไร ถา ความสมั พนั ธน้นั สามารถที่จะเขยี น class แยกกนัออกมาได การออกแบบก็ควรใหเปน class ทแ่ี ยกกันอยู เพราะจะทําใหก ารออกแบบทําไดง า ยกวา การสรางและเรยี กใช object ก็จะไมซ ับซอ นเทาใดนักมาถึงตอนนีเ้ ราไดทราบถงึ การสรา ง class การออกแบบ method และการสราง object จาก classพอสมควร ตวั อยางทจ่ี ะแสดงใหดตู อ ไปเปนความพยายามทจ่ี ะออกแบบ class Array ขึ้นมาใชงานเพือ่ ทจ่ี ะแสดงใหเห็นถึงศกั ยภาพของการใช Java ในการเขยี นโปรแกรมclass MyArray ทเี่ ราสรา งข้นึ จะกําหนดใหเ ปน array ท่ีใชเกบ็ Object เพอ่ื ใหม คี วามยดื หยนุ ในการทํางานกบั ขอ มลู ตา ง ๆ ทั้งนแี้ ละทง้ั นนั้ class MyArray เปนเพียงแคต วั อยา งตัวอยางหนึ่งเทา นัน้ ผอู า นสามารถทจี่ ะทาํ ไดมากกวาทีโ่ ปรแกรมตัวอยางนแี้ สดงใหด ู//MyArray.javaclass MyArray { //array of objects Object []arr; //maximum size of array int maxSize; //number of items in array int count;//default constructorMyArray() { ภาควิชาคอมพิวเตอรธรุ กจิ วทิ ยาลัยฟารอ ีสเทอรน

บทที่ 5 Objects และ Classes 159เริม่ ตน กับ Java count = 0; //no item as yet maxSize = 10; //default maximum size arr = new Object[maxSize]; //allocate space for arr}//constructorMyArray(int size) { count = 0; //no item as yet maxSize = size; //set maximum size arr = new Object[maxSize]; //allocate space for arr}//method to add item into arrpublic void add(Object item) { //expand capacity if arr is full //double the size if(count == maxSize) { //double arr's size maxSize *= 2; //create temporary array Object []temp = new Object[maxSize]; //copy items into new array: temp System.arraycopy(arr, 0, temp, 0, arr.length); //refer arr to temp arr = temp; } arr[count++] = item; //add new object into arr}//overload method add to accomodate doublepublic void add(double item) { add(String.valueOf(item));}//overload method add to accomodate intpublic void add(int item) { add(String.valueOf(item));} //return formatted output when user uses System.out.println() //10 items per line public String toString() { //create new buffer to hold data StringBuffer buffer = new StringBuffer(); for(int i = 0; i < maxSize; i++) { //append newline if this line already has 10 items if(i % 10 == 0) buffer.append(\"\n\"); //stop appending when there is no item left (null) if(arr[i] == null) break; //append tab + item in arr buffer.append(\"\t\" + arr[i]); } //returning an output String return new String(buffer + \"\n\"); }} ภาควิชาคอมพิวเตอรธุรกจิ วิทยาลัยฟารอ ีสเทอรน

บทท่ี 5 Objects และ Classes 160เริม่ ตนกบั Javaเรากาํ หนดใหมี constructor สองตัว โดยท่ตี วั แรกเปน default constructor ที่กาํ หนดใหข นาดของarray มีความจคุ ร้งั แรกไดเ พยี ง 10 ตัว สวนตวั ทส่ี องเปน constructor ทผ่ี ูใชสามารถกาํ หนดขนาดของarray ได เราไดออกแบบให array ของเราเปน array แบบยืดหยนุ หรอื ทเี่ รยี กวา dynamic array โดยเรากาํ หนดใหม กี ารขยายขนาดของ array ใหเปน สองเทาของขนาดเดมิ ถา มกี ารใสข อ มูลเกนิ จํานวนที่array สามารถรองรบั ได ใน method add()public void add(Object item) { //expand capacity if arr is full //double the size if(count == maxSize) { //double arr's size maxSize *= 2; //create temporary array Object []temp = new Object[maxSize]; //copy items into new array: temp System.arraycopy(arr, 0, temp, 0, arr.length); //refer arr to temp arr = temp; } arr[count++] = item; //add new object into arr}method add() ของเราจะตรวจสอบคา ของ count (จาํ นวนของขอมลู ที่มอี ยใู น array) กบั maxSize(ความจสุ ูงสดุ ทสี่ ามารถเกบ็ ขอ มูลได) วา เปน คาเดียวกนั หรอื ไม ถาเปนคา เดียวกันเราจะขยายขนาดของarray ออกเปน สองเทา ดว ยการสราง array ตัวใหมช อ่ื temp ท่มี คี วามยาวเปน สองเทาของ array ตัวเดิมmaxSize *= 2;Object []temp = new Object[maxSize];หลงั จากนั้นเราก็ทําการโยกยายขอ มลู จาก array ตวั เกา สู array temp ดวยการใชค าํ ส่งัSystem.arraycopy(arr, 0, temp, 0, arr.length);คําส่ังนจ้ี ะทาํ การยายขอ มูลจาก arr เริ่มตน ท่ี index = 0 ไปสู temp เรม่ิ ตนที่ index 0 จนกวาจะหมดความยาวท่กี าํ หนดให (arr.length) ซง่ึ ก็คือจาํ นวนของขอมูลท่ีอยใู น arr ทัง้ หมดเมอ่ื โยกยา ยขอ มลู เสรจ็ แลว เรากอ็ า งถงึ array ตัวใหมด ว ย array ตัวเดมิ ของเราคอื arr ดวยคาํ ส่ังarr = temp;เรายังไดท าํ การ overload method add() ของเราเพ่ือใหสามารถรองรบั การเพิ่มขอ มูลทีเ่ ปน double และint เขาสู array ของเราได วิธีการแบบน้ไี มค อ ยจะดสี ักเทาไร เพราะเปนการนําเอาขอมูลทไี่ มใชช นดิเดียวกัน (โดยตรง) เขาไปเกบ็ ไวใน array ซง่ึ ถา หากมีกระบวนการอ่นื ๆ ท่ีเราตองการทาํ กบั ขอมูลเหลาน้นั เราจะตอ งเสยี เวลาในการตรวจสอบชนิดของขอ มูลทุกตวั ท่มี อี ยใู น array ของเราเราทําการ overload ดวยการใช method ของ class String คอื String.valueOf() ดังท่ีเห็นนี้public void add(double item) { add(String.valueOf(item));}เนอื่ งจากวา String เปน Object ชนิดหนึ่งดงั นน้ั การ add String เขา สู array ของเราจึงไมม ปี ญหาอะไรหลงั จากนน้ั เราไดเขยี นโปรแกรมเพ่อื ตรวจสอบ ดงั นี้ ภาควิชาคอมพิวเตอรธรุ กจิ วิทยาลยั ฟารอ ีสเทอรน

บทท่ี 5 Objects และ Classes 161เริม่ ตนกบั Java//TestMyArray.javaimport java.lang.Integer;class TestMyArray { public static void main(String[] args) { //create array of 10 objects MyArray array = new MyArray(10); //add 40 objects into array (randomized) int count = 0; while(count < 40) { int data = (int)(Math.random() * 100 + 1); array.add(new Integer(data)); ++count; } System.out.println(array); //display contents array.add(45.23); //add double array.add(88.23); array.add(89); //add int array.add(12); System.out.println(array); }}เราก็ไดผลลัพธ ดังน้ี 9 76 20 86 98 12 27 35 41 31 54 65 83 3 36 96 24 63 19 75 3 91 87 72 3 12 7 46 96 11 1 70 27 47 14 51 22 74 95 98 9 76 20 86 98 12 27 35 41 31 54 65 83 3 36 96 24 63 19 75 3 91 87 72 3 12 7 46 96 11 1 70 27 47 14 51 22 74 95 98 45.23 88.23 89 12ผอู านควรสงั เกตถึงผลลพั ธท ไี่ ดโดยเฉพาะขอมลู ในบรรทดั สดุ ทาย (ท่เี ราไดเ พิม่ ขอมลู ทีเ่ ปน double และint หลังจากการ display ครัง้ แรก)สว นประกอบทส่ี ําคญั อีกสวนหน่ึงท่ีตองกลาวไวใ นท่ีนี้ คอื method toString() และกอนทจี่ ะพูดถึงmethod toString() เราควรดปู ระโยคอีกประโยคหน่งึ กอ น นน่ั กค็ อืSystem.out.println(array);ประโยค System.our.println() จะรับเฉพาะขอ มูลที่เปน String หรอื primitive datatype ทเ่ี ราไดพดู ถงึกอ นหนา น้ี แตส ิง่ ที่เราสง ไปใหเ ปน object จาก class MyArray ทาํ ไมเราถงึ ทําได?เราสง Object ไปให System.out.println() ไดกเ็ พราะวา เราไดเขียน method toString() รองรับไวเรยี บรอ ยแลว เม่ือไรกต็ ามที่ Java เห็นขอมูลทีไ่ มใ ช String หรือ primitive datatype Java จะทําการคนหา method toString() ถา มี Java ก็จะใช method toString() น้นั แตถ า ไมม กี ็จะฟองดว ย errorทนั ที เรามาดกู นั วาเราเขยี น method toString() อยา งไร ภาควิชาคอมพิวเตอรธรุ กจิ วทิ ยาลัยฟารอสี เทอรน

บทที่ 5 Objects และ Classes 162เร่ิมตนกบั Javapublic String toString() { //create new buffer to hold data StringBuffer buffer = new StringBuffer(); for(int i = 0; i < maxSize; i++) { //append newline if this line already has 10 items if(i % 10 == 0) buffer.append(\"\n\"); //stop appending when there is no item left (null) if(arr[i] == null) break; //append tab + item in arr buffer.append(\"\t\" + arr[i]); } //returning an output String return new String(buffer + \"\n\");}ภายใน method toString() เราใช StringBuffer ในการเกบ็ สว นประกอบตาง ๆ ท่เี ราตองการสงกลับออกไป ซ่ึงจะประกอบไปดว ยƒ ขอมลู ตา ง ๆ ทอ่ี ยใู น array (arr[i])ƒ tab (\t)ƒ newline (\n)เรานาํ ขอ มูลเหลา น้ไี ปเกบ็ ไวใน buffer ดวยการใช method append() ทกุ ๆ ครัง้ ทีเ่ ราไดข อ มลู ครบ 10ตวั เราจะทาํ การ append newline เขา สู buffer ถาหากวา เราไดขยายขนาดของ array แตไ มไ ดใสข อ มลูครบตามขนาดท่ไี ดข ยายข้นึ เราจะยุติการนาํ ขอ มลู เขาสู buffer เนื่องจากวาขอมลู เหลา นม้ี คี า เปน nullและเรากไ็ มต อ งการแสดงคา เหลาน้ี เม่ือเราไดขอมลู ท้ังหมดท่ีตอ งการแลว เรากส็ ง กลบั ออกไป โดยสงออกไปในรูปแบบของ String (เพราะ System.out.println() ตองการ String) ดว ยคําสงั่return new String(buffer + \"\n\");ผูอา นสามารถนาํ เอาเทคนคิ นีไ้ ปใชกบั การแสดงขอมูลอ่ืน ๆ ผา นทาง System.out.println() ไดโดยไมม ีขอ จํากัดใด ๆ ทั้งสนิ้เราสามารถทจ่ี ะสรา ง class เพ่อื การใชงานของเราโดยไมมขี ีดจาํ กัดใด ๆ ทั้งน้กี ็ตอ งขึ้นอยกู ับลกั ษณะงานนัน้ ๆ วา อยใู นรปู แบบไหน ความยาก งา ยของงานเปนอยางไร ตัวอยา งการสรา ง array ขึ้นมาใชงานเปนเพียงตวั อยา งเลก็ ๆ เพยี งตัวอยา งเดยี วที่เราไดแ สดงใหด ถู งึ ขอ ดขี องภาษา Java ยังมสี ่งิ อนื่ ๆ ที่ผูอา นสามารถทจ่ี ะสรา งข้นึ มาสาํ หรบั งานของตัวเองไดPackagePackage เปนทีร่ วมของ class ตาง ๆ ท่ีถกู เรยี กใชใ นโปรแกรม หรือ method ตา ง ๆ class ทกุ ๆ ตวั ของJava ไดถูกจัดถูกเก็บอยใู น package ตา ง ๆ เชน java.lang หรอื java.io การเอา class ตา ง ๆ มารวมกนัไวใน package เดียวกันทาํ ใหก ารเรยี กใช class ตา ง ๆ เหลา นที้ ําไดง ายขึน้ ถาผูอ านมองยอ นกลับไปดูโปรแกรมตัวอยา งตาง ๆ ที่เราเขียนขึน้ ก็จะเหน็ การเรียกใช package เหลา นใ้ี นโปรแกรมหลาย ๆ ตัว เราจะมาดถู งึ วธิ กี ารสราง package เพื่อเก็บ class และการเรยี กใช package เหลา น้ใี นโปรแกรมตัวอยา งการสรา ง packageการสรา ง package นน้ั ไมย าก ขัน้ ตอนก็ไมซ ับซอนเทาไร ขน้ั ตอนแรกทเี่ ราตอ งทํากค็ อื ใสค ําวาpackage ตามดว ย ชื่อของ package น้ันกอนประโยคใด ๆ ในไฟลท ี่เก็บ class นนั้ ๆ ท่ีเราสรา งข้นึ(ยกเวนประโยคที่เปน comment) เชน//package Shapepackage Shape; ภาควิชาคอมพิวเตอรธุรกจิ วทิ ยาลัยฟารอสี เทอรน

บทท่ี 5 Objects และ Classes 163เรม่ิ ตน กับ Javapublic class Rectangle { … …}ถา เราไมใสคาํ วา public ไวด านหนา ของ class หรือ method ที่อยูใน package ทเ่ี ราสรางขนึ้ โปรแกรมหรอื class ตัวอนื่ ๆ ท่อี ยูนอก package ก็ไมสามารถทีจ่ ะเรยี กใช class นไ้ี ด ยกเวน class อื่น ๆ ที่อยใู นpackage นีเ้ ทาน้ัน package ตวั อยา งของเราใชช ื่อวา Sample โดยเรากาํ หนดให Sample ประกอบไปดวย class One และ class Two และเราไดส ราง package อกี ตวั หนงึ่ ใน Sample ใหช่อื วา oneMoreและใน package oneMore นเ้ี ราจะเก็บ class Three ไว ดังท่เี ห็นจาก code ขางลางน้ี//sample packagepackage Sample;public class One { public One() { System.out.println(\"This is class One in Sample package.\"); }}//sample packagepackage Sample;public class Two { public Two() { System.out.println(\"This is class Two in Sample package.\"); }}//sample packagepackage Sample.oneMore;public class Three { public Three() { System.out.println(\"This is class Three in Sample.oneMorepackage.\"); }}ในการ compile ไฟลท ั้งสามทีไ่ ดส รางข้ึนน้ี เราใชค าํ ส่งั javac -d e:\bc221Book\source ตามดวยช่อืไฟล เชน javac -d e:\bc221Book\source One.javaเราตอ งใช option -d ในการ compile ไฟลท งั้ สามเพอื่ บอกให Java รูถึงแฟม ปลายทางที่เราตองการเกบ็class ไฟลที่เกดิ ข้ึนจากการ compile ในท่ีน้เี ราจะเก็บ class ไฟลไวใ น e:\bc221Book\sourceภายในไฟล One.java และ Two.java เราไดใ ชค าํ สง่ั package Sample เปนตัวบอกถึงทเ่ี ก็บ class ไฟลและในตวั ไฟล Three.java เราใชค ําสัง่ package Sample.oneMore เพราะฉะนั้น class ไฟลท ่ีเกิดขึ้นจะถูกเก็บไวในแฟม (directory) เหลา น้ี ดงั ท่ไี ดแ สดงไวในรูปทเี่ ห็นดานลางน้ี ภาควิชาคอมพิวเตอรธุรกจิ วทิ ยาลัยฟารอสี เทอรน

บทท่ี 5 Objects และ Classes 164เรมิ่ ตนกบั Java Package ชอ่ื Sample ใน e:\bc221Book\source Package ชอ่ื oneMore ใน e:\bc221Book\source\Sample Class ไฟลท ถ่ี กู สรางข้ึนรปู ท่ี 5.7 แฟมเกบ็ class file ทเ่ี กดิ ข้นึ จากการ compile ดวย option -dหลงั จากน้ันเรากส็ รา งโปรแกรมตรวจสอบการเรยี กใช package ที่เราไดส รา งขน้ึ โดยทีเ่ รากําหนดใหม ีการเรยี กใช class ตาง ๆ ดว ยการใชค าํ สั่ง import ดังน้ี//test the packageimport Sample.One;import Sample.Two;import Sample.oneMore.Three;class TestPackage { public static void main(String[] args) { One object1 = new One(); Two object2 = new Two(); Three object3 = new Three(); }}หลงั จากนน้ั เราก็ compile โปรแกรม TestPackage.java ดว ยคาํ สง่ัjavac -classpath e:\bc221Book\source TestPackage.javaโดยเราใช option –classpath ตามดว ยท่อี ยขู อง class ตา ง ๆ ทเ่ี ราไดส รา งข้ึนในการ compile และเมือ่ทดลอง run ดผู ลลัพธท ไ่ี ดค อืThis is class One in Sample package.This is class Two in Sample package.This is class Three in Sample.oneMore package.ในการสราง package นัน้ Java จะไปสรางแฟมทมี่ ชี อ่ื เหมือนกบั ทเี่ รากาํ หนดไว ดังทไี่ ดเ ห็นในตวั อยางและเราสามารถที่จะกาํ หนด sub-directory ดว ยการใช . (dot) เชน ทีเ่ ราไดท าํ ไว (Sample.oneMore)และเราตองไมล มื ใชค ําวา public นาํ หนา class และ method ตา ง ๆ ที่เราตอ งการใหโปรแกรม หรอืclass หรือ method อ่นื ๆ ทีอ่ ยูนอก package ใชเราไมจ าํ เปน ตอ ง compile ดว ยการใชคาํ ส่งั ทมี่ ี option –classpath ในการ compile โปรแกรมทเี่ รียกใชpackage ตาง ๆ ของ Java เพราะ Java ไดจดั การเรอ่ื งตา ง ๆ เหลา นใ้ี หเ ราเรียบรอ ยแลวถาเราใช class ตาง ๆ ท่ีอยใู น package ท่สี รา งข้ึนบอยคร้ัง หรอื ทุกคร้ัง เรากส็ ามารถที่จะกาํ หนดใหJava คน หา class ตา ง ๆ เหลา น้โี ดยไมต องกําหนด option –d ในการ compile เราเพยี งแตก ําหนดclasspath ไวก อนการ compile ครัง้ แรกเพียงครง้ั เดยี ว ดังนี้ ภาควิชาคอมพิวเตอรธ ุรกจิ วทิ ยาลยั ฟารอสี เทอรน

บทท่ี 5 Objects และ Classes 165เร่มิ ตน กบั Javaset classpath=e:\bc221Book\sourceถา เราไมอยากทจี่ ะกําหนด classpath ทกุ ครงั้ ที่เราตอง compile เราก็กาํ หนด classpath ไวใ นไฟลautoexec.bat สาํ หรบั Windows รนุ เกา ๆ สว น Windows รนุ ใหมเราตอ งกําหนด classpath ไวใ นenvironment variables (คลา ย ๆ กบั การกาํ หนด path ของ Java ในบทที่หนง่ึ ) ถาเรามี package อืน่ ๆท่เี ราตอ งการใช เราก็ใช ; เปนตวั แบง classpath เชนset classpath=e:\bc221Book\source; c:\myOthers\Shapeสรปุในบทนเ้ี ราไดสาํ รวจถึงวิธีการสรา ง class การสราง object การสราง method และการสราง method และconstructor ทมี่ ี signature ท่แี ตกตางกนั ในการรองรับการเรยี กใชด ว ย parameter ท่ตี า งกนั การกาํ หนดนโยบายการเขา หาขอมลู ท่ีอยใู น class รวมไปถึงการสราง nested class และการสราง package โดยสรปุ แลวเราไดท ราบถงึ9 สวนประกอบของ class9 ช่อื ของ class จะตองเปนช่ือเดียวกันกับๆฟลท เี่ ก็บ class น้นั อยู9 การประกาศตัวแปรทเี่ รียกวา class variable ตอ งใชค าํ วา static นําหนา9 ตัวแปรที่เปน instance variable สามารถท่จี ะเขา หาไดผ านทาง object ที่เกดิ จาก class น้ัน9 การสรา ง method จะตองบอกถงึ สิ่งทีต่ อ งสง กลบั ชนิดและจํานวนของ parameter (ถาม)ี9 Method ท่ีประกาศใหเ ปน static สามารถถกู เรยี กใชไดถงึ แมว า จะไมมี object ใด ๆ ถูกสรางขนึ้9 การเขาหาขอ มลู ใน class มีสามแบบคอื private public และ protected (ไมนบั แบบทไี่ มมคี าํ ใด ๆ นาํ หนา)9 การสราง class สามารถท่ีจะสรางใหอยูใ น class อนื่ ได9 การสรา ง และ การใช package จะตอ งใชคาํ วา public นาํ หนา class หรอื method ที่ตองการให ผูอื่นทอ่ี ยูนอก package ใชแบบฝก หดั1. จงออกแบบ class ทใ่ี ชเ ก็บขอ มูลเกย่ี วกบั นักศึกษา เชน รหัส ช่อื -นามสกลุ ทอี่ ยู และขอ มูลอื่น ๆ ที่ เหน็ วา เหมาะสม ใหเขยี นโปรแกรมทดสอบการสรา ง object ตา ง ๆ จาก class ทีไ่ ดส รางขนึ้ นี้2. จงออกแบบ class ที่ใชเ ก็บขอ มลู ทีเ่ กี่ยวขอ งกบั นา้ํ หนกั เชน ตัน กโิ ลกรมั และ กรัม โดยใหอ อกแบบ ใหม ี constructor ทรี่ องรับการสรา ง object ดว ยจาํ นวน parameter ท่ตี า งกนั ชนิดของ parameter ที่ตา งกัน รวมไปถึงการออกแบบ method ทท่ี ําการบวก การลบ object ตาง ๆ ทไ่ี ดถูกสรา งข้ึน ให เขยี นโปรแกรมทดสอบ3. จาก class MyArray ทส่ี ามารถเก็บขอ มลู ที่เปน object ตางชนดิ กันได จากตวั อยางทใี่ หไ ว จงเขียน method ท่ีสงจาํ นวน object ที่มีอยูใน array ใหช่อื วา getCount() และ method dataAt() ทสี่ ง คา ของขอ มลู ณ ตาํ แหนง ท่ีกาํ หนดใหก ลบั ไปยงั ผูเ รียก เชน ถา เรยี กดวย Object obj = arr.dataAt(7); จะสงขอ มลู ณ ตาํ แหนงที่ 7 มาใหกบั ตวั แปร obj ใหเ ขียนโปรแกรมทดสอบ method ทเี่ ขยี นข้นึ4. จงเขยี นโปรแกรมที่มี method ในการคํานวณหาพืน้ ที่ของวงกลมทีม่ ี parameter ตา งชนดิ กนั เชน ผู เรียกใช method อาจสง ขอ มูลท่มี ชี นดิ เปน int double float หรือ String ท่ีเปนตัวเลข เชน \"234\" ใหเขยี นโปรแกรมตรวจสอบ method เหลา น้ี5. จงเขยี นโปรแกรมทต่ี รวจสอบการใช overloaded constructor ในการกาํ หนดคาใหกับ instance variable ทีม่ ีอยูใน class นน้ั ๆ ใหเขียนโปรแกรมทดสอบ ภาควิชาคอมพิวเตอรธุรกิจ วิทยาลยั ฟารอ ีสเทอรน

บทที่ 5 Objects และ Classes 166เริม่ ตน กบั Java6. จงออกแบบ class สําหรับเกบ็ ขอ มูลทเี่ กี่ยวขอ งกบั นักศึกษา เชน รหสั ประจาํ ตวั ช่อื นามสกลุ ทีอ่ ยู และขอ มลู อื่น ๆ ทจ่ี าํ เปน รวมไปถงึ method ตาง ๆ ที่ใชใ นการกาํ หนดคา หรอื ประมวลผลเกรดเฉลยี่ และ method สําหรบั การแสดงผลไปยังหนา จอ7. จงออกแบบ class สาํ หรบั เก็บขอ มูลของ วนั เดอื น ป ในรปู แบบของ dd:mm:yyyy โดยกาํ หนดให ขอมลู นน้ี าํ เขามาจาก keyboard ใหเขยี น Method ทีท่ าํ หนา ทใ่ี นการเปล่ยี นขอ มูลนี้ใหอ ยใู นรปู แบบ ที่ขนึ้ ตนดวย วนั ตามดวย วนั ที่ เดือน และ ป เชน วนั จนั ทรท ี่ 12 สิงหาคม พ.ศ. 2546 หรอื Monday 12 August 2003 ใหเขียนโปรแกรมทดสอบ8. จงออกแบบ class Matrix สาํ หรบั การประมวลผลตา ง ๆ เชน การบวก การลบ การคณู และ กระบวนการอน่ื ๆ ทีเ่ กี่ยวขอ ง ใหเขียนโปรแกรมทดสอบ9. จงออกแบบ class ท่ใี ชส าํ หรบั การคํานวณหาอายุของ user ทใ่ี สเ ขามาจาก keyboard ในรปู แบบ ของ dd/mm/yyy โดยใหผลลพั ธท ห่ี าไดอยูใ นรปู แบบของ จาํ นวนของวนั ทง้ั หมด ใหเ ขยี นโปรแกรม ทดสอบ10. จงออกแบบ class MyString ท่ีมี method สําหรบั การประมวลทเี่ กย่ี วของกบั string ตาง ๆ เชน การ บวก string สองตวั การคน หาคาํ ใน string การลบคาํ ทอ่ี ยูใ น string การนับจํานวนตวั อักษรท่ีอยใู น string ใหเ ขยี นโปรแกรมทดสอบ ภาควิชาคอมพิวเตอรธ ุรกิจ วทิ ยาลัยฟารอีสเทอรน

เราไดพ ูดถงึ การสรา ง class และสวนประกอบตา ง ๆ ทสี่ าํ คญั ของ class รวมไปถึงการสรา ง method ในบททหี่ า สาํ หรบั บททหี่ กน้ีเราจะสํารวจในเรื่องของการสรา ง class ใหมจาก class เดมิ ท่มี ีอยู การนําเอาสว นประกอบของ class เดมิ มาใชใน class ใหม การถา ยทอดคณุ สมบตั แิ ละ กระบวนการตา ง ๆ จาก classเดมิ สู class ใหมหลังจากจบบทน้ีแลว ผอู านจะไดทราบถงึ เรือ่ งของ o การใช class เดมิ สาํ หรับการสรา ง class ใหม (Extended class) o การถายทอดคณุ สมบัติ (Inheritance) o คุณสมบตั ิ และการใชประโยชนจ าก polymorphism o การสราง abstract class และ abstract method o การใช และ การสรา ง interfaceการสราง class ใหมจาก class เดิมทม่ี อี ยแู ลวเปนการพัฒนาโปรแกรมทท่ี ําใหก ารเขียน code ใชเ วลานอ ย และเปนการใช code อยางคุมคาทส่ี ดุ Java ยอมใหมีการสราง class เดิมจาก class ใหมไดอยา งงาย ๆ โดยทผี่ ูเขยี นโปรแกรมแทบจะไมตอ งทาํ อะไรมากมาย (ยกเวน code ใหมท ่เี ขยี นขน้ึ ) กอนทีจ่ ะพดูถงึ ศัพทตาง ๆ ที่เกี่ยวขอ งกบั การสราง class ใหมจาก class เดิมเราจะมาดกู ันถึงตวั อยางของการสรา งclass ใหมจาก class เดมิ กอ นเราจะเริ่มตนดวยการสรา ง class งา ย ๆ class หนึง่ ทเี่ กี่ยวกับรถทใ่ี ชเ คร่ืองยนต (motor vehicle) โดยกาํ หนดใหมีขอ มูลทไี่ มซับซอน เชน ยหี่ อ (make) รุน (model) ปท ีผ่ ลติ (year) และ จาํ นวนทน่ี ่ัง (seats)พรอ มทัง้ กาํ หนดใหม ี method สาํ หรับการเขาหาขอมูลเหลานน้ั หลงั จากทไี่ ด class MotorVehicle แลวเราก็ออกแบบ class อ่นื ๆ ทีไ่ ดร บั คณุ สมบตั จิ าก class MotorVehicle ดงั ท่แี สดงใหเหน็ คราว ๆ จากdiagram น้ี (เราจะดโู ครงสรา งของ class ท้ังหมดตอไป) MotorVehicle Car MotorcycleCompact OffRoad Scooter Chopperภาพที่ 6.1 ตัวอยา งของ base-class และ derived-class

บทท่ี 6 การสราง class ใหมจาก class เดิม และ การถา ยทอดคุณสมบตั ิ 168เร่ิมตนกับ Javaเราออกแบบให class MotorVehicle เปน class แมแบบ หรอื ทีเ่ รียกวา parent class (หรอื base classหรือ super class) ซ่ึงจะเปน class ท่อี ยูดานบนสุดของ class ตาง ๆ ในกลมุ นี้ เรากําหนดให classMotorVehicle มี class ลูก (children) อยูสอง class คอื class Car และ class Motorcycle class ลูกท้งัสองตา งก็มี class ทีเ่ ปน ลูกของมนั เองอกี สอง class โดยท่ี class Car มลี ูกเปน class Compact และclass OffRoad สวน class Motorcycle มี class Scooter และ class Chopper เปน class ลกู เราจะกําหนดให class ลูกไดรับคณุ สมบัตจิ าก class แมท ั้งหมด คอื ขอ มลู ทกุ ตวั ทีม่ ีอยูใ น class MotorVehicleเรามาดกู นั ถึง ขอมูล และ method ที่เรากาํ หนดใหม ใี น class MotorVehicle//MotorVehicle.java – Inheritanceclass MotorVehicle { //e.g. Ford, Honda protected String make; //e.g. Taurus, Steed protected String model; //e.g. 2001, 2003. protected int year; //e.g. 4, 2 protected int seats;//constructorMotorVehicle(String make, String model, int year, int seats) { this.make = make; this.model = model; this.year = year; this.seats = seats;}public String getMake() { return make;}public String getModel() { return model;}public int getYear() { return year;} public int getSeats() { return seats; }}เรากาํ หนดใหตวั แปรที่มอี ยใู น class MotorVehicle ใชน โยบายของการเขาหาแบบ protected ซ่ึงเปนการกาํ หนดให class ลกู ทเ่ี กิดขน้ึ จาก class MotorVehicle สามารถท่จี ะเรยี กใชต ัวแปรเหลานี้ได class อน่ื ๆที่ไมไดมาจาก class น้จี ะมองไมเหน็ ขอมูลเหลา น้ี เรากาํ หนดใหมี constructor เพยี งตวั เดียวสาํ หรับการสรา ง object โดยเราเลือกใชค าํ ส่งั this ในการแยกแยะตวั แปรที่อยใู น class กบั ตวั แปรที่เปน parameterMotorVehicle(String make, String model, int year, int seats) { this.make = make; this.model = model; this.year = year; this.seats = seats;}คําวา this เปน คําที่ Java สงวนไวส ําหรบั การบงบอกถงึ object ทไี่ ดรับการกระทําดวยกระบวนการตาง ๆณ เวลานน้ั ๆ เชนในตวั อยางประโยคthis.make = make; ภาควิชาคอมพิวเตอรธ รุ กจิ วิทยาลยั ฟารอสี เทอรน

บทท่ี 6 การสราง class ใหมจ าก class เดมิ และ การถา ยทอดคุณสมบัติ 169เริ่มตน กับ Javaเมื่อ Java ประมวลผล constructor ตวั น้ี Java จะทาํ การกาํ หนดคา จากตวั แปร make ทเี่ ปน parameterของ constructor ใหกับตวั แปร make ท่อี ยใู น class ซงึ่ เปน copy ที่ object ตัวนใ้ี ชอ ยูเราไมจ าํ เปนทจ่ี ะตองใช this เปน ตวั บงบอกตัวแปรเสมอไป ถาเราใชตัวแปรท่อี ยใู น parameter list ที่มีชือ่ ไมเ หมอื นกับ ตัวแปรของ class (เชนตวั อยางอื่น ๆ ทเ่ี ราไดแสดงไวในบททหี่ า) สว น method อนื่ ๆ ท่ีมีอยูกเ็ ปน เพียง method ทสี่ ง คาของตัวแปรเหลานี้ใหก ับผูเรยี ก สําหรับ class อนื่ ๆ ทีเ่ ราไดสรางขนึ้ มีดงั น้ี//Car.java - Derived from MotorVehicleclass Car extends MotorVehicle { protected int doors; Car(String make, String model, int year, int seats, int doors) { super(make, model, year, seats); this.doors = doors; } public int getDoors() { return doors; } //display Car's information as string //using base class methods public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(super.getMake() + \", \" + super.getModel() + \", \" + super.getYear() + \", \" + \" seating: \" + super.getSeats() + \", \" + doors + \"doors.\"); return new String(buffer); }}เราสรา ง class Car จาก class MotorVehicle ดวยการใชค ําสั่ง class Car extends MotorVehicle ซงึ่เปนคาํ ส่ังท่ี Java กาํ หนดใหใชถาตองการสรา ง class ใหมท ตี่ องการใชคณุ สมบตั ิของ class อนื่ภายใน class Car ทีเ่ ราไดสรา งขึน้ เรากาํ หนดใหม ีตวั แปรหนงึ่ ตัวทเ่ี ปนตวั กําหนดจํานวนของประตทู ่ีรถคันนม้ี อี ยู และเพ่ือใหก ารแสดงผลไปยงั หนาจอทําไดง ายข้ึน เราก็สรา ง method toString() สาํ หรับการแสดงผลของ object ทเ่ี กดิ จาก class Car ของเรา เราเรยี กขอมูลท่เี ราไดร บั การถา ยทอดจาก classMotorVehicle ดว ยการใชค ําสงั่ ดงั นี้super.getMake();เม่อื Java เหน็ การใชค าํ สงั่ แบบน้ี Java ก็จะไปคนหา method getMake() ท่ีอยใู น class ท่ีเปน class แมหรือทีเ่ รยี กกันวา super class พรอ มท้ังประมวลผลคาํ ส่งั ตา ง ๆ ทมี่ อี ยใู น method getMake()ผูอ า นจะเหน็ วาเราไมต อ งประกาศตัวแปรขึน้ มาใชใ หมใ น class Car ของเราเลย เราสามารถเรยี กใชต ัวแปรเหลานจี้ าก class MotorVehicle ไดเลย เรามาทดสอบ class ท้ังสองดวยการสราง object จาก classCar สองตวั เชน ท่ีเห็นในโปรแกรม TestVehicle.java น้ี//TestVehicle.javaclass TestVehicle { public static void main(String[] args) { //create two cars, ford and honda ภาควิชาคอมพิวเตอรธ ุรกจิ วทิ ยาลยั ฟารอีสเทอรน

บทที่ 6 การสราง class ใหมจาก class เดิม และ การถา ยทอดคุณสมบตั ิ 170เร่ิมตนกบั JavaCar ford = new Car(\"Ford\", \"Taurus\", 2001, 5, 5);Car honda = new Car(\"Honda\", \"City\", 2003, 4, 4); //display informatin about cars System.out.println(ford); System.out.println(honda); }}ผลลัพธท ีเ่ ราไดจากการ run คือFord, Taurus, 2001, seating: 5, 5 doors.Honda, City, 2003, seating: 4, 4 doors.เราไดใ ชน โยบายการเขาหาแบบทใี่ ชคาํ วา protected ซงึ่ เราไมไดอ ธิบายไวเ ลยกอ นหนา นี้ สาเหตกุ ็เนอ่ื งจากวา คาํ วา protected โดยสว นใหญจะใชก ันในเรือ่ งของการถายทอดคุณสมบตั จิ าก class แมไ ปยังclass ลูก โดยกาํ หนดไววา class ลกู สามารถท่จี ะใชต วั แปร (หรือ method ท่ใี ชคําวา protected นําหนา)จาก class แมไดอ ยางไมมีเงอื่ นไข แตถ าเราใชคาํ วา private แทน class ลกู ไมส ามารถทจ่ี ะเขาหาตวัแปร หรือ method เหลา นไี้ ด ดังตวั อยา งตอไปน้ีCar(String make, String model, int year, int seats, int doors) { super(make, model, year, seats); this.doors = doors; System.out.println(\"base class: \" + super.make);}ใน class MotorVehicle เราเปลย่ี นนโยบายการเขา หาตวั แปร make ใหเปน privateprivate String make;และเพมิ่ ประโยคSystem.out.println(\"base class: \" + super.make);ใน constructor ของ class Car ซ่ึงเปนประโยคทพ่ี ยายามเขา หาตัวแปรใน class MotorVehicle ดวยการใช super.make Java จะไมย อมใหเรา compile พรอมกบั ฟอ งวาเราไมสามารถเขา หาตัวแปรตัวน้ีได วิธีเดียวทเ่ี ราจะเขา หาตัวแปรเหลา นี้ได ก็คอื การเขา ผา นทาง method getMake() ท่ีเราไดกาํ หนดนโยบายการเขาหาใหเ ปน public เทา นน้ัโดยท่ัวไปเรามกั จะกาํ หนดใหต วั แปรทใ่ี ชร ว มกันใน class ลกู (ที่มีอยใู น class แม) ทงั้ หลายมนี โยบายการเขาหาที่เปน แบบ private เพือ่ ปองกันการใชท ไี่ มพงึ ประสงคจ าก class อืน่ และเราก็ควรจะกําหนดใหmethod ทีอ่ ยใู น base class มนี โยบายการเขาหาทีเ่ ปนแบบ protected ดว ยเหตผุ ลเชนเดยี วกนั และเหตุผลอกี อันหนง่ึ กค็ อื คาํ วา protected เมอ่ื มีการนาํ มาใชแ ลว class อ่นื ๆ ที่อยูใ น package เดยี วกนั ก็สามารถทจี่ ะเขา หาตวั แปร หรอื method เหลา น้ีได ดงั นนั้ ถา ตองการให class ตา ง ๆ ของเราทส่ี รา งขน้ึ ในตัวอยางเปน class ท่กี ารใชนโยบายการเขาอยางถกู ตอง เราก็ตองเปลีย่ น class ของเราใหเปน ดงั น้ีclass MotorVehicle {private String make; //e.g. Ford, Hondaprivate String model; //e.g. Taurus, Steedprivate int year; //e.g. 2001, 2003private int seats; //e.g. 4, 2//constructorMotorVehicle(String make, String model, int year, int seats) { this.make = make; this.model = model; this.year = year; ภาควิชาคอมพิวเตอรธ ุรกจิ วิทยาลยั ฟารอ ีสเทอรน

บทท่ี 6 การสรา ง class ใหมจ าก class เดิม และ การถา ยทอดคุณสมบัติ 171เร่ิมตน กับ Java this.seats = seats; } protected String getMake() { return make; } protected String getModel() { return model; } protected int getYear() { return year; } protected int getSeats() { return seats; }}class Car extends MotorVehicle { private int doors; Car(String make, String model, int year, int seats, int doors) { super(make, model, year, seats); this.doors = doors; } protected int getDoors() { return doors; } public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(super.getMake() + \", \" + super.getModel() + \", \" + super.getYear() + \", \" + \"seating: \" + super.getSeats() + \", \" + doors + \" doors.\"); return new String(buffer); }}เราไมส ามารถทจี่ ะเปลยี่ นนโยบายการเขาหาของ method toString() ใหเ ปน protected ไดก เ็ พราะวาJava ไดกําหนดใหก ารเขาหาของ method toString() เปนแบบ public ไวแลว ซง่ึ เราจะไดอ ธบิ ายตอไปในเร่ืองของการ overrideเพือ่ ใหเ ห็นถงึ ความพิเศษของ การถายทอดคณุ สมบัติ และเพือ่ เปน การแนะนาํ เรื่องของการ override เราจะสรา ง class Compact ข้นึ มาอกี class หนงึ่ โดยกาํ หนดให class Compact นเ้ี ปน class ท่ีไดรบั การถายทอดคณุ สมบัติจาก class Car ดงั นี้//Compact.java Derived from Carclass Compact extends Car { //constructor -using base class (Car) constructor Compact(String make, String model, int year, int seats, int doors) { super(make, model, year, seats, doors); ภาควิชาคอมพิวเตอรธุรกิจ วิทยาลัยฟารอ สี เทอรน

บทท่ี 6 การสราง class ใหมจาก class เดิม และ การถายทอดคุณสมบัติ 172เริ่มตนกบั Java } //override Car's toString() method //presenting Comapct car's details as string public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(\"Compact car: \"); buffer.append(super.toString()); return new String(buffer); }}class Compact ของเราเรยี กใชขอมลู ทกุ อยา งที่ class แมม ใี ห ตวั แรกทเ่ี ราเรียกใชกค็ ือ constructorของ class Car (ซ่ึง constructor ของ class Car ก็เรยี กใช constructor ของ class MotorVehicle) ตวั ท่ีสองท่ีเราเรยี กใชก ็คอื method toString() ของ class Car ซึ่งเราไดเพิม่ คาํ วา \"Compact car: \" ไวก อ นหนาขอมลู อนื่ ๆ ดว ยการใช method append() ของ class StringBuffer ดงั น้ีbuffer.append(\"Compact car: \");buffer.append(super.toString());เม่อื ทดลอง run ดว ยการใชค าํ สงั่Compact honda = new Compact(\"Honda\", \"City\", 2003, 4, 4);System.out.println(honda);ผลลพั ธท ่ไี ด คอืCompact car: Honda, City, 2003, seating: 4, 4 doors.ซ่งึ ตา งจากการ run กอ นหนานี้ (ตอนทเ่ี ราสรา ง object จาก class Car)เราใชเ ทคนคิ ทเี่ รียกวา method overriding ในการแสดงผลขอมลู ของ object ท่เี กิดจาก classCompact ในการ override (ซึง่ ตางกับ overload ทเี่ ราไดท ํากอ นหนานี้ – overload ทาํ กับ method ที่อยูใ น class เดียวกนั และตอ งเปน method ทมี่ ี parameter list ไมเหมือนกัน) method จาก class แมหรอื ทีเ่ รยี กวา base class นนั้ เราสามารถทจี่ ะเขยี น code ใหท ํางานในลกั ษณะใดกไ็ ด โดยท่วั ไปการoverride method ทาํ ใหก ารเรยี กใชง านทาํ ไดง า ยขน้ึ ไมส ับสน เพราะ method ชอ่ื เดียวกนั มีอยใู น classทุกตัว แตท ําหนา ทต่ี ามที่ไดก าํ หนดไวใ น method ของ class นัน้ ๆเราสามารถทจี่ ะ override method ทีม่ อี ยูใ น class แมไ ดทกุ ตวั และ object ท่เี กิดจาก class ลูก หรือท่ีเรียกวา derived class นัน้ เมอ่ื มกี ารเรยี กใช method ที่ไดรบั การ override Java จะไปเรยี ก method ที่อยใู น class ลกู ไมใ ช method ทีอ่ ยใู น class แมจากตวั อยา งของ class Compact ทไ่ี ดกลาวไว เราไดใ ชท ง้ั การถา ยทอดคณุ สมบตั ิ และการ overridemethod โดยเราไดรบั การถา ยทอดในเรือ่ งของตวั แปร และไดใ ชเ ทคนคิ การ override ในการใช methodtoString()Method ทไี่ ดร บั การ override ใน class ลกู นั้นไมสามารถทจ่ี ะเปลี่ยนแปลงนโยบายของการเขาหาใหเ ปนอยางอน่ื ทมี่ คี วามเขม งวดกวาได เชน ถา method ใน class แมมีนโยบายการเขา หาทเ่ี ปน public ในclass ลกู ก็ไมสามารถทจ่ี ะเปลยี่ นใหเ ปน private ไดเพราะการเขา หาแบบ private นน้ั เขมงวดมากกวาแตถา ใน class แมน โยบายเปน private เราสามารถทจ่ี ะเปลยี่ นใหเปน public ได พดู งา ย ๆ ก็คอื วา เราเพิ่มความเขมงวดนโยบายการเขาหาใน class ลูกไมได แตลดลงไดเรามาลองดตู ัวอยา งของการถา ยทอดคณุ สมบัตกิ ันอีกสักตวั อยางหน่งึ สมมตวิ า เรามี class ตา ง ๆ ดงั ที่แสดงใน diagram นี้ ภาควิชาคอมพิวเตอรธ ุรกิจ วิทยาลัยฟารอีสเทอรน

บทท่ี 6 การสราง class ใหมจาก class เดมิ และ การถายทอดคุณสมบตั ิ 173เรมิ่ ตนกบั Java Shapes Polygons CircleTriangle Rectangle Squareภาพท่ี 6.2 ตวั อยา ง class ที่เก่ียวของกบั shape ตา ง ๆโดยกาํ หนดใหก ารถา ยทอดคณุ สมบัตเิ ปนไปดงั ทเ่ี หน็ ใน diagram คอื Shapes เปน base classPolygons และ Circle เปน class ลกู ของ Shapes สว น Triangle Rectangle และ Square เกิดมาจากclass Polygonsในทกุ ๆ class เรากาํ หนดใหม ี method what() เพยี ง method เดียว ดงั ทแ่ี สดงไวใ น code ทีเ่ หน็ นี้//Shapes.java - Base class for all shapesclass Shapes { //self info. protected String what() { return \"I am a shape\";}//Polygons.java – Polygonclass Polygons extends Shapes { //self info. protected String what() { return \"I am a polygon.\"; }}//Circle.java - sub-class of Shapesclass Circle extends Shapes { //self info protected String what() { return \"I am a circle.\"; }}//Triangle.java - sub-class of Polygonsclass Triangle extends Polygons { //self info. protected String what() { return \"I am a triangle.\"; }}//Square.java - sub-class of Polygons ภาควิชาคอมพิวเตอรธ รุ กิจ วิทยาลยั ฟารอ สี เทอรน

บทท่ี 6 การสรา ง class ใหมจาก class เดมิ และ การถา ยทอดคุณสมบัติ 174เร่ิมตนกบั Javaclass Square extends Polygons { //self info. protected String what() { return \"I am a square.\"; }}//Rectangle.java - sub-class of Polygonsclass Rectangle extends Polygons { //self info. protected String what() { return \"I am a rectangle.\"; }}เราเขยี นกําหนดใหโปรแกรมตรวจสอบเปนดังน้ี//TestShapes.java - driver programclass TestShapes { public static void main(String[] args) { //creating different shape objects from Shapes Shapes shape = new Shapes(); Shapes poly = new Polygons(); Shapes sq = new Square(); Shapes cir = new Circle(); //display info. about particular shapes System.out.println(shape.what()); System.out.println(sq.what()); System.out.println(cir.what()); System.out.println(poly.what()); }}ในโปรแกรมตรวจสอบเราไดสราง object สต่ี วั จาก class Shapes แตท าํ การกําหนดการสรา งผา นทางconstructor ของ class น้นั ๆ ทีเ่ ราตอ งการสราง เชนShapes sq = new Square();ถา มองดอู ยา งผิวเผนิ จะเห็นวา การประกาศแบบนไ้ี มน า ทจ่ี ะทําได เนอ่ื งจากวา เรากาํ หนดให sq เปนobject ท่มี สี ถานะเปน Shapes แตกลับไปเรียก constructor ของ Square แต Java ยอมใหการสรา งobject แบบนี้เกิดขน้ึ ไดก็เพราะวา Square เปน class ทเี่ กดิ มาจาก class Shapes (พูดงาย ๆ ก็คอื Circleเปน Shapes แบบหน่ึง) และภายใน class Shapes เรากาํ หนดใหมี method what() อยู ดงั นน้ั class ลกูที่เกิดมากส็ ามารถทีจ่ ะเขาหา method นี้ไดแ ต ภายในตวั class ลูกท้ังหมดกม็ ี method what() อยดู ังนัน้การเรียก method what() ขึน้ มาใชจ ึงเปน การเรยี ก method ทีม่ ีอยภู ายใน class ลูก (overriding) ดงั ท่ีแสดงใหเ หน็ จากผลลพั ธน ี้I am a shapeI am a square.I am a circle.I am a polygon. ภาควิชาคอมพิวเตอรธุรกจิ วทิ ยาลยั ฟารอสี เทอรน

บทที่ 6 การสรา ง class ใหมจ าก class เดมิ และ การถา ยทอดคุณสมบัติ 175เริม่ ตน กบั JavaPolymorphism (ความมีรปู แบบทหี่ ลากหลาย)การทํางานในลกั ษณะที่ไดกลา วมาน้ันเราเรยี กวา late binding หรอื ท่เี รยี กกันมากมายในหนังสือหลาย ๆเลมวา polymorphism ซง่ึ หมายถึงความเปลย่ี นแปลงรปู แบบตามสภาพของ object ที่ไดถ กู สรา งขนึ้ หรอืที่เปน อยู คําวา late binding หมายถึงเวลาท่ี compiler จัดสรรหนวยความจําใหก บั ตวั แปรในขณะท่ีโปรแกรมกําลงั ถกู execute (run อยู) ไมใชใ นขณะทก่ี าํ ลัง compile โปรแกรมPolymorphism ทําไดเ ฉพาะ method เทา น้ันเราไมส ามารถจะใชว ธิ กี ารแบบนกี้ บั ตวั แปรท่อี ยใู น classได การเขา หาตวั แปรจะตอ งทาํ ผา นทาง object ที่เกิดจาก class นนั้ ๆ เทาน้นัสมมตวิ า เราตอ งการทจ่ี ะเขยี น method ท่คี าํ นวณหาเสน รอบวงของ object ตา ง ๆ ทสี่ รา งข้ึนมาจากclass Shapes เราก็อาจทาํ ไดด วยการเขียน method ลงไปใน class นั้น ๆ (ทถ่ี กู สรา งมาจาก class แม)แตการกระทาํ ดงั กลาวคงไมคอยดีเทา ไรนกั ถา เราไมร วู า object ที่เราตอ งการสรา งขน้ึ มานน้ั รปู รา งหนาตาเปน อยา งไร และคงจะไมคอยเขาทา เทา ไรนกั ทีจ่ ะหาเสน รอบวงของ shape ท่ีเรายังไมรูวา เปน shapeอะไร แต Java เอ้อื โอกาสใหเ ราสามารถทีจ่ ะประกาศ (declare) method ใน class แมแตไปกาํ หนดหนาที่ (define) ใน class ลกู วิธีการดงั กลาวเราเรยี กวา การสราง abstract classAbstract class เปน class ท่ีมกี ารประกาศ method ใน class แม แตไมม กี ารกาํ หนดหนา ที่ใด ๆ เรอ่ื งของการกําหนดหนา ท่จี ะเปน ภาระของ class ลูก ดงั เชน ตัวอยางตอไปนี้//Shapes.java - Base class for all shapespublic abstract class Shapes { private String iAm; Shapes(String whatIam) { iAm = new String(whatIam); } //self info. public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(\"I am a \" + iAm); return new String(buffer); } //dummy method - implementation is done in derived classes //to calculate a perimeter of a shape public abstract double perimeter();}เราเปลี่ยนแปลง class Shapes ของเราใหเปน abstract class พรอ มทงั้ ประกาศ method perimeter() ที่ไมมี code ใด ๆ อยูเลย หลังจากน้นั เราก็สรา ง class อืน่ ๆ ท่ีไดรบั การถา ยทอดคณุ สมบตั จิ าก classShapes ดงั น้ี//Polygons.java – Polygonpublic abstract class Polygons extends Shapes { //constructor Polygons(String type) { super(type); } //self info. public String toString() { return super.toString(); ภาควิชาคอมพิวเตอรธ รุ กิจ วทิ ยาลัยฟารอ สี เทอรน

บทที่ 6 การสราง class ใหมจ าก class เดิม และ การถา ยทอดคุณสมบตั ิ 176เริม่ ตน กบั Java} //dummy method to be implemented by derived classes public abstract double perimeter();}//Triangle.java - sub-class of Polygonspublic class Triangle extends Polygons { private double side1, side2, side3;//constructorTriangle(String type, double side1, double side2, double side3) { super(type); //calling base-class constructor this.side1 = side1; this.side2 = side2; this.side3 = side3;}//self info.public String toString() { return super.toString();} //calculating a perimeter of this triangle public double perimeter() { return side1 + side2+ side3; }}//Circle.java - sub-class of Shapespublic class Circle extends Shapes { private double radius;//constructorCircle(String type, double radius) { super(type); this.radius = radius;}//self infopublic String toString() { return super.toString();} //calculating a perimeter of this circle public double perimeter() { return 2.0 * Math.PI * radius; }}//Square.java - sub-class of Polygonspublic class Square extends Polygons { double side;//constructor ภาควิชาคอมพิวเตอรธุรกิจ วทิ ยาลัยฟารอีสเทอรน

บทท่ี 6 การสรา ง class ใหมจ าก class เดิม และ การถา ยทอดคุณสมบตั ิ 177เริ่มตนกับ Java Square(String type, double side) { super(type); this.side = side; } //self info. public String toString() { return super.toString(); } //calculating a perimeter of this square public double perimeter() { return side * 4; }}หลังจากทีเ่ ราไดส ราง class Polygons class Circle class Triangle และ class Square พรอ มทง้ั กําหนดหนา ท่ขี อง method perimeter() ใน class Circle class Triangle และ class Square เรยี บรอ ยแลว เราก็เขียนโปรแกรมเพื่อตรวจสอบวา method ของเราใชง านไดถ กู ตองหรอื ไม ดงั น้ี//TestShapes.java - driver programclass TestShapes { public static void main(String[] args) { Shapes cir, tri; Polygons sq; //instantiate shapes sq = new Square(\"square\", 4.0); cir = new Circle(\"circle\", 2.0); tri = new Triangle(\"triangle\", 3.0, 4.0, 5.0); //display info. about particular shapes System.out.println(sq + \" with a perimeter of: \" + sq.perimeter()); System.out.println(cir + \" with a perimeter of: \" + cir.perimeter()); System.out.println(tri + \" with a perimeter of: \" + tri.perimeter()); }}ในโปรแกรม TestShapes.java เราประกาศตวั แปร cir และ tri จาก class Shapes ตวั แปร sq จาก classPolygons สาเหตทุ เ่ี ราประกาศตัวแปรแทนการสราง object กเ็ พราะวา Java ไมยอมใหเ ราทําเนอ่ื งจากวา class Shapes และ class Polygons เปน class ที่ถกู กาํ หนดใหเปน abstract class แตเราสามารถทีจ่ ะใชต ัวแปรทัง้ สามในการสรา ง object (instantiation) จาก class Circle class Square และclass Triangle ไดประโยคในการสราง object ทงั้ สามsq = new Square(\"square\", 4.0);cir = new Circle(\"circle\", 2.0);tri = new Triangle(\"triangle\", 3.0, 4.0, 5.0);อาจดูแปลกไปจากการสรา ง object ทเ่ี ราไดเ คยทาํ มา แตเราสามารถทาํ ไดก ็เพราะวา class Shapes เปนbase class ของ class ท้ังหมด สวน class Polygons ก็เปน base class ของ class Square และ class ภาควิชาคอมพิวเตอรธุรกจิ วทิ ยาลยั ฟารอสี เทอรน

บทท่ี 6 การสราง class ใหมจาก class เดิม และ การถายทอดคุณสมบตั ิ 178เริม่ ตนกบั JavaTriangle การสรา ง object ท้งั สามจึงสามารถทําได พดู งาย ๆ ก็คอื วา ทั้ง sq cir และ tri ตางก็เปนshape ทงั้ น้ัน (e.g. a square is a shape, a circle is a shape, a triangle is a shape etc.)ผลลพั ธท เ่ี ราไดจากการ run คือI am a square with a perimeter of: 16.0I am a circle with a perimeter of: 12.566370614359172I am a triangle with a perimeter of: 12.0Polymorphism มปี ระโยชนม ากในการกาํ หนดหนา ที่ของ method ที่ object ตา ง ๆ ใชรว มกนั ซึง่ หนา ที่ตาง ๆ เหลานจี้ ะข้ึนอยูกับคุณลกั ษณะของ object ทเี่ กดิ จาก class น้ัน ๆ ดังท่ีเราไดแสดงใหดูในการหาเสนรอบวงของรูปทรงตาง ๆ หากเราตอ งการเรากส็ ามารถทจ่ี ะสรา ง array ในการเก็บ shape ตาง ๆเหลาน้ีได ดังตวั อยางทแ่ี สดงใหเหน็ น้ี//TestShapes.java - driver programclass TestShapes { public static void main(String[] args) { Shapes []shapes = new Shapes[5]; //instantiate 5 shapes for(int i = 0; i < 5; i++) shapes[i] = randomShape(); //display info. about particular shapes for(int i = 0; i < 5; i++) { System.out.print(shapes[i] + \" with a perimeter of: \"); System.out.println(shapes[i].perimeter()); } } public static Shapes randomShape() { switch((int)(Math.random() * 3)) { default: case 0: return new Circle(\"circle\", Math.random() * 12.0); case 1: return new Square(\"square\", Math.random() * 10.5); case 2: return new Triangle(\"triangle\", 2.5, 4.0, 5.5); } }}เราเลอื กที่จะใหการสรา งรูปทรงตา ง ๆ เกิดแบบ random ดังนัน้ เราจึงเขียน method randomShape()ข้ึนมาใชส ําหรบั การสรางรูปทรงท่ีไมมขี อ กําหนดท่ีตายตวั รปู ทรงทเ่ี กดิ ข้นึ จะถกู กําหนดโดย methodrandom() ของ class Mathผลลัพธท ่ีไดจ ากการ run คอืI am a square with a perimeter of: 15.282560130191253I am a triangle with a perimeter of: 12.0I am a circle with a perimeter of: 0.209235603993188I am a triangle with a perimeter of: 12.0I am a circle with a perimeter of: 7.8292546239806695หากเราอยากรวู า object ทส่ี รา งขน้ึ มานน้ั เกิดจาก class อะไรเรากส็ ามารถหาไดจ ากการใช methodgetClass() และ method getName() ทม่ี ีอยใู น class Class ของ Java เชน ถาเราตอ งการรูวา object ท่ีshapes[0] เกบ็ ไวเ กดิ มาจาก class อะไรเรากใ็ ชคําส่ังดงั น้ี ภาควิชาคอมพิวเตอรธ รุ กิจ วิทยาลยั ฟารอสี เทอรน

บทที่ 6 การสรา ง class ใหมจาก class เดิม และ การถายทอดคุณสมบัติ 179เร่มิ ตน กบั JavaClass object = shapes[0].getClass();System.out.println(object.getName());ถาเราอยากรูวา object ตัวนี้มี class แมห รอื ไมเรากใ็ ช method getSuperclass() เชนClass shape = object.getSuperclass();System.out.println(shape.getName());ยงั มี method ใน class Class อกี หลายตวั ทเ่ี ราสามารถนาํ มาใชได แตโดยสว นใหญแ ลว เราแทบท่ีจะไมตอ งใช method เหลาน้ใี นการพฒั นาโปรแกรมทว่ั ไปเลย เพราะ method เหลานจี้ ะใหข อ มูลท่เี กี่ยวกับclass ท่ผี ูใช (หรอื ของ Java) สรางขน้ึ มาเทา น้นั เองการสง และรบั objectตวั อยา งตอไปน้เี ปนการสง object เขาไปใน method พรอมกบั การสง object กลับดวยการเปล่ยี นแปลงบางอยาง สมมติวาเราตองการสรา ง วงกลมจาก สเี่ หลี่ยมดา นเทาที่มีอยแู ลว เรากอ็ าจเขียน method ท่ีทาํ หนา ทน่ี ใ้ี หเรา ดงั นี้//SquareToCircle.java - Passing and returning object to/from methodclass SquareToCircle { public static void main(String []args) { Shapes square; //a square object Shapes circle; //a circle object //creating a square with side = 3 square = new Square(\"square\", 3.0); System.out.println(square + \" with an area of \" + square.area()); //creating a circle from a square circle = SqToCir(square); System.out.println(circle + \" with an area of \" + circle.area()); } //method to convert a square to a circle public static Shapes SqToCir(Shapes square) { //finding a radius from an area of a square double SqArea = square.area(); double radius = Math.sqrt(SqArea / Math.PI); //instantiating a circle Circle circle = new Circle(\"circle\", radius); return circle; }}เพื่อใหการทาํ งานของเราประสพผลสาํ เรจ็ เราไดเ พม่ิ abstract method area() ใน class Shapes และclass Polygons และทาํ การกาํ หนดหนา ที่ของ method area() ใน class Square และ class Circle ซงึ่เปน การคํานวณหาพืน้ ทข่ี องรปู ทรงทีไ่ ดถ ูกสรา งขน้ึใน class Shapes เรากาํ หนด ดังนี้ (ใน class Polygons กท็ าํ แบบเดียวกนั )public abstract class Shapes { … ภาควิชาคอมพิวเตอรธ ุรกิจ วิทยาลยั ฟารอสี เทอรน

บทที่ 6 การสรา ง class ใหมจ าก class เดิม และ การถา ยทอดคุณสมบตั ิ 180เร่ิมตน กบั Java … //code อน่ื ๆ เหมอื นเดิม … … public abstract double perimeter(); public abstract double area();}ใน class Circle เรากาํ หนด code ของ method area() ดงั น้ี//calculate area of this circlepublic double area() { return Math.PI * radius * radius;}และใน class Square เรากาํ หนด code ของ method area() ดังน้ี//calculate area of this squarepublic double area() { return side * side;}ในตัวโปรแกรมของเรา เราสรา ง object สองตวั คือ square และ circle โดยกําหนดให square มีความยาวของดานแตละดา นเทากบั 3.0 หลงั จากทแี่ สดงขอมลู ของ square เรียบรอยแลว เรากส็ ง square ไปให method SqToCir() ซ่งึ เปน method ท่ีทาํ การเปลย่ี น square ใหเปน circle โดยกําหนดใหท ง้ั สองobject มพี ื้นท่เี ทากนัpublic static Shapes SqToCir(Shapes square) { //finding a radius from an area of a square double SqArea = square.area(); double radius = Math.sqrt(SqArea / Math.PI); //instantiating a circle Circle circle = new Circle(\"circle\", radius); return circle;}เราเริ่มตน ดวยการหาพืน้ ที่ของ square ทส่ี งเขามา หลังจากนน้ั เราก็หารศั มขี องวงกลมทเ่ี ราตอ งการสรางจากพน้ื ท่ี ท่ีหาได เมือ่ ไดแลวเราก็สรา ง circle ดว ยรัศมีน้ี เสรจ็ แลว จึงสง วงกลมท่ไี ดนีก้ ลับไปผลลัพธท ีเ่ ราไดจากการ run โปรแกรมของเราคอืI am a square with an area of 9.0I am a circle with an area of 9.0ขอดีของการกาํ หนดให base class เปน abstract class นั้น กค็ อื เราไมตองกําหนดหนาทขี่ อง methodใน class แม เพราะวา เราอาจไมร ขู อ มลู ทงั้ หมดที่ method ตองการใช ดังเชน method perimeter() และmethod area() เนอื่ งจากวา เรายังไมร ูว า shape ทมี่ ีอยเู ปน object ชนดิ อะไร ขอมูลเปน อยางไร แตเ รารูขอมลู ทั้งหมดท่ี Circle และ Square ตอ งการใชในการคํานวณหาเสนรอบวง และพน้ื ทจี่ าก การสรางobject ของ class ทั้งสอง ภาควิชาคอมพิวเตอรธรุ กจิ วทิ ยาลยั ฟารอ สี เทอรน

บทท่ี 6 การสรา ง class ใหมจาก class เดมิ และ การถายทอดคุณสมบตั ิ 181เร่ิมตน กบั Javaการสรา ง Interfaceจากเทคนคิ การใช polymorphism ในตวั อยางกอ นหนา นี้ เราตองกําหนดใหม ี method ใน class แม และไปกาํ หนดหนาที่ของ method เหลา นใี้ น class ลกู ซึง่ เปน การสรา ง class ในลักษณะที่ซ้ําซอ นพอสมควรถาเราตอ งคณุ สมบัติของ polymorphism ใน class ทีเ่ กดิ จาก class แมนี้ เราก็ไมจําเปนทจ่ี ะตองสรางclass แมข้นึ มา แตไปสรา ง interface ขึน้ มาแทนInterface เปนที่รวบรวมคาคงที่ และ abstract method ตาง ๆ ท่จี ะตอ งมกี ารเรียกใชใ น class อนื่ ๆ ท่ีเรยี ก interface น้ไี ปใช การสรา ง interface กไ็ มย าก แทนทีเ่ ราจะใชค าํ วา class เรากใ็ ชคําวา interfaceแทน เราจะใช class ตาง ๆ ทเ่ี ราไดสรางไวก อ นหนา น้ีในเรอ่ื งของรูปทรงตา ง ๆ เปนตัวอยา ง และเราจะตอ งทําการเปลย่ี นแปลง class ตาง ๆ ดงั น้ีใน class Shapes และ class Polygons เราจะตัดเอา abstract method perimeter() และ area() ออกพรอมกบั เปลีย่ นการประกาศ class Shapes ใหเปนดงั น้ีpublic abstract class Shapes implements Calculate { private String iAm; Shapes(String whatIam) { iAm = new String(whatIam); } //self info. public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(\"I am a \" + iAm); return new String(buffer); }}เราเพม่ิ คําวา implements Calculate เขาสดู านหลังสุดของ class Shapes โดยมีเงอ่ื นไขวา เราตองมีinterface ช่อื Calculate อยแู ลว การสรา ง interface กท็ ําไดไ มย าก เราเพยี งแตก าํ หนดให Calculateเปนชอ่ื ของ interface ทเี่ ราตอ งการใช พรอ มทัง้ กาํ หนดใหม ี method ตา ง ๆ ทีเ่ ราตองการทจ่ี ะใหม ีในclass อน่ื ๆ เชน//interface for Shapespublic interface Calculate { double perimeter(); double area();}ในการเขยี น Method ทอี่ ยูใ น interface นั้นเราไมจําเปน ท่ีจะตอ งกาํ หนดนโยบายของการเขา หา การกาํ หนดนโยบายจะตอ งทาํ ใน class ท่เี รียกใช (implement) interface นี้class อืน่ ๆ ท่เี หลอื อยกู ็ไมมกี ารเปลี่ยนแปลงอะไรมากมาย ยกเวน การคํานวณหาพนื้ ท่ีของรูปทรงตา ง ๆใน class Triangle เราเพม่ิ method//calculating an area of this triangle//using Huron's formulapublic double area() { double s = perimeter() / 2.0; double area = Math.sqrt((s * (s-side1) * (s-side2) * (s-side3))); return area;} ภาควิชาคอมพิวเตอรธ รุ กิจ วทิ ยาลยั ฟารอีสเทอรน

บทที่ 6 การสราง class ใหมจาก class เดิม และ การถา ยทอดคุณสมบัติ 182เรม่ิ ตนกับ Javaใน class Circle เราเพมิ่ method//calculate area of this circlepublic double area() { return Math.PI * radius * radius;}ใน class Square เราเพมิ่ method//calculate area of this squarepublic double area() { return side * side;}หลังจากท่ีเปลยี่ นแปลง code บางสวนในโปรแกรมทดสอบ ดังน้ี//TestShapes.java - driver programimport java.text.DecimalFormat;class TestShapes { public static void main(String[] args) { Shapes []shapes = new Shapes[5]; //instantiate 5 shapes for(int i = 0; i < 5; i++) shapes[i] = randomShape(); //display info. about particular shapes DecimalFormat f = new DecimalFormat(\"0.00\"); for(int i = 0; i < 5; i++) { System.out.print(shapes[i] + \" perimeter = \"); System.out.print(f.format(shapes[i].perimeter())); System.out.println(\" area = \" + f.format(shapes[i].area())); } } public static Shapes randomShape() { switch((int)(Math.random() * 3)) { default: case 0: return new Circle(\"circle\", Math.random() * 12.0); case 1: return new Square(\"square\", Math.random() * 10.0); case 2: return new Triangle(\"triangle\", 4.0, 5.0, 6.0); } }}ผลลพั ธท ไี่ ดค อืI am a triangle perimeter = 15.0 area = 9.90I am a square perimeter = 10.32 area = 6066I am a circle perimeter = 45.32 area = 163.46I am a triangle perimeter = 15.00 area = 9.92I am a circle perimeter = 6.76 area = 3.64 ภาควิชาคอมพิวเตอรธรุ กิจ วิทยาลยั ฟารอ ีสเทอรน

บทที่ 6 การสรา ง class ใหมจ าก class เดิม และ การถา ยทอดคุณสมบัติ 183เริ่มตน กบั Javaเนื่องจากวา เราไดทาํ การเรยี กใช interface Calculate ใน class แม ดงั นน้ั เราไมจ าํ เปน ทีจ่ ะตองเรียกใชinterface Calculate ใน class ลูกเพราะ class ลกู เหลา น้ีไดรบั การถา ยทอดคณุ สมบตั จิ าก class แมเรยี บรอ ยแลว เหตผุ ลอีกอยางหน่ึงทีเ่ รากาํ หนดให class Shapes มกี าร implements Calculate กค็ อื เราไมตอ งการเปลย่ี นแปลง code ที่เราไดเขยี นข้ึนกอนหนานม้ี ากมายนักเรามาลองดตู ัวอยางของการใช interface ที่ Java มใี หส ักตวั อยา งหน่งึ โดยเราจะเรียกใช interfaceActionListener ในการตรวจจบั เหตุการณท ีจ่ ะเกดิ ขน้ึ จากตัวโปรแกรม ตัวอยา งน้อี าจมขี อ มลู ทเี่ รายังไมไ ดพดู ถงึ มากพอสมควร แตป ระเดน็ หลกั ทตี่ อ งการแสดงกค็ อื การเรยี กใช interface เราจะปรบั ปรุงโปรแกรมInterests.java ท่ีเราไดเขียนขึ้นในบททส่ี าม ซ่งึ เปนโปรแกรมสําหรบั การคาํ นวณหาดอกเบี้ยทบตน เราจะสรา ง class ข้นึ ใหมด ังน้ีclass Account ใชเ ปนการเก็บ balance คํานวณดอกเบ้ยี แสดงผล class น้ีเรียกใช interface BankRateclass Timer เปน class ท่มี ีอยใู น Java ใชส าํ หรับการกระทาํ ทีต่ องใชเวลาclass Interests1 เปนโปรแกรมทดสอบสว นตา ง ๆ ทเี่ ราสรางขึน้interface BankRate ใชเ ก็บคา คงที่ RATE ทใี่ ชในการคาํ นวณหาดอกเบีย้interface ActionListener ใชใ นการตรวจสอบเหตุการณท เ่ี กดิ จากผใู ชโ ปรแกรม เชน ออกจากโปรแกรมเรากําหนดใหความสัมพนั ธข อง class เปน ไปตาม diagram ที่เห็นนี้ Account GetInterest BankRate ActionListener interface Timerภาพที่ 6.2 การเรยี กใช interfaceเราเริ่มตน ดวย interface BankRate และ class Account//interface for bank ratepublic interface BankRate { double RATE = 5.0;}//Account.javapublic class Account implements BankRate { private double balance; //constructor - initializing balance Account(double balance) { this.balance = balance; } //method to get balance protected double getBalance() { return balance; } //method to deposit ภาควิชาคอมพิวเตอรธ รุ กจิ วิทยาลยั ฟารอ สี เทอรน

บทท่ี 6 การสราง class ใหมจาก class เดิม และ การถายทอดคุณสมบตั ิ 184เริ่มตน กบั Java protected void deposit(double amount) { balance += amount; } //method to calculate interest protected double interest() { return balance * RATE / 100.0; } //method to display info. about this account public String toString() { return \"Balance = \" + getBalance(); }}เราเขียน class Account อยางงา ย ๆ โดยกาํ หนดใหม ี method สําหรบั การกาํ หนด balance การคาํ นวณหาดอกเบ้ยี และการแสดงผลผานทาง method toString() ตอไปเราจะมาดู class Interests1 ซึ่งเปน โปรแกรมทดสอบการใชงานของ class และ interface//Interests1.javaimport java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JOptionPane;import javax.swing.Timer;class Interests1 { public static void main(String[] args) { //create account with initial balance of 1000 final Account acc = new Account(1000); //inner class performing interest calculation //and listening to event from user //stop performing when user hit stop button in //the dialog window class GetInterest implements ActionListener { public void actionPerformed(ActionEvent event) { double ints = acc.interest(); acc.deposit(ints); System.out.println(acc); } } //create object from class GetInterest GetInterest intsPeek = new GetInterest(); //set performing time interval to one second final int DELAY = 1000; //calling actionPerformed() every 1000 milliseconds Timer t = new Timer(DELAY, intsPeek); //start the timer t.start(); //display dialog window - stop performing and exit //program when user hit the button JOptionPane.showMessageDialog(null, \"Stop?\"); System.exit(0); }} ภาควิชาคอมพิวเตอรธรุ กิจ วิทยาลยั ฟารอ สี เทอรน

บทที่ 6 การสราง class ใหมจ าก class เดมิ และ การถา ยทอดคุณสมบตั ิ 185เริม่ ตนกบั Javaในโปรแกรม Interests1.java เราสรา ง object acc จาก class Account ดวยคา balance เร่ิมตนท่ี 1000ภายใน method main() เราสราง class GetInterest ท่เี รยี กใช interface ActionListener ของ Java ซงึ่จะคอยตรวจสอบเหตกุ ารณ (event) ทีอ่ าจเกิดขน้ึ จาก user พรอ มทั้งการคาํ นวณหาดอกเบ้ียmethod actionPerformed() จะถกู เรียกโดย object intsPeek จาก class Timer ดว ยคา delay 1 วนิ าทีดว ยประโยคน้ีTimer t = new Timer(DELAY, intsPeek);แตกระบวนการท้ังหมดจะเรมิ่ ไดด วยการเรยี ก method start() ของ class Timer ดงั น้ี t.start()โปรแกรมของเราจะคาํ นวณหาดอกเบ้ยี ไปจนกวา user จะกดปมุ OK ท่ีแสดงไวใน dialog window ที่ปรากฏอยใู นหนา จอ ซง่ึ dialog window น้ีถกู สรางข้นึ มาดวยคําสงั่JOptionPane.showMessageDialog(null, \"Stop?\");ซึง่ มหี นา ตาดงั น้ีเมือ่ user กดปมุ OK เรากจ็ ะยตุ โิ ปรแกรม และออกจากระบบดว ยคําสงั่ System.exit(0);ตวั อยา งผลลัพธทีไ่ ดจ ากการ run โปรแกรมในชว งเวลาหนง่ึ กอนการกดปมุ คือBalance = 1050.0Balance = 1102.5Balance = 1157.625Balance = 1215.50625Balance = 1276.2815624999998Balance = 1340.0956406249998Balance = 1407.1004226562497Balance = 1477.4554437890622Balance = 1551.3282159785153Balance = 1628.894626777441Balance = 1710.3393581163132Balance = 1795.8563260221288Balance = 1885.649142323235Balance = 1979.931599439397เราตองการท่จี ะแสดงใหเ ห็นถงึ การใช interface ทั้งท่มี อี ยใู น Java และที่เขยี นขึ้นเอง สว นการใชสว นประกอบอื่น ๆ ท่ี Java มใี หเปนเพยี งสงิ่ ทีผ่ ูอานจะไดส มั ผสั ในโอกาสตอไปเรามีทางเลือกสองทางในการสราง และกาํ หนดหนาที่ของ method ดงั ทีเ่ ราไดพ ดู ไว คอื1. กําหนดให class แมเ ปน abstract class พรอมท้งั กําหนดใหม ี ชื่อของ method ทต่ี อ งการ การ กําหนดหนาทข่ี อง method จะเปนภาระของ class ลูกเอง ภาควิชาคอมพิวเตอรธรุ กิจ วิทยาลัยฟารอ ีสเทอรน

บทท่ี 6 การสรา ง class ใหมจ าก class เดมิ และ การถา ยทอดคุณสมบัติ 186เริม่ ตน กบั Java2. กาํ หนดให class เรียกใช interface ท่ีมกี ารกาํ หนดชอื่ ของ method และ class ตองกาํ หนดหนาที่ ของ method น้นั เองสรปุเราไดพ ดู ถึงการสราง class ใหมจ าก class ทมี่ ีอยกู อนแลว การถายทอดคณุ สมบัติจาก class แมสู classลกู การ override method การใช polymorphism การสรา งและใช interface โดยสรุปแลว สง่ิ สําคญั ท่ีเราไดพ ูดไวค ือ9 เราสามารถสรา ง class ใหมจาก class ทีม่ อี ยกู อ นแลว ดวยการใชคาํ วา extends ซ่งึ class ทีเ่ รา extends มานั้นเราเรยี กวา base class หรือ parent สวน class ทเี่ ราสรา งขึน้ ใหมเราเรยี กวา sub class หรือ child9 เราสรา ง abstract class ดวยการใชค ําวา abstract ซง่ึ ภายใน class ทีเ่ ปน abstract class นั้นจะมี method ประกาศอยู แตหนา ทีข่ อง method ยงั ไมไ ดถ กู กําหนด การกาํ หนดจะทาํ ใน class ลูกเดทา นน้ั และเราไมส ามารถที่จะสรา ง object จาก abstract class ได9 sub class ไมไ ดรับการถายทอด constructor ของ super class9 ถาเรากาํ หนดนโยบายการเขา หาของ method หรอื ตัวแปรใหเปน private ใน class แม class ลูกจะ ไมสามารถเขาหาตวั แปร หรือ method ได9 ตวั แปรที่ประกาศจาก class แมส ามารถทีจ่ ะใชเปนตัวชี้ไปยงั object ของ class ลูกได ซง่ึ ทําใหก าร เรียกใช method ทีอ่ ยูใน class ลกู เปนไปได9 abstract class เปน class ที่ไมตองกําหนดหนา ท่ใี ห method ทุก ๆ ตวั ใน class9 interface ประกอบไปดวย คา คงที่ abstract method และ inner class9 class ทีไ่ มกําหนดหนาทใ่ี หก ับ method ทุกตวั ท่ีตวั มนั เองตอ งใช interface จะตอ งประกาศใหเ ปน abstract classแบบฝก หดั1. จากขอ มูลทใ่ี หเ ปนคูในแตล ะขอ จงแสดงถึงความสัมพันธว าสวนไหนเปน super class และสว นไหน เปน sub classผูจัดการ ลกู จางนักศึกษา อาจารยคน นักศกึ ษาอาจารย บคุ ลากรสามี ภรรยาพอ ลูก2. สมมตวิ า class RumRaisin extends มาจาก class Icecream จงหาวา ประโยคใดตอไปน้ีเปน ประโยคที่ Java ยอมรับRumRaisin scoop1 = new RumRaisin();Icecream scoop2 = new Icecream;scoop2 = scoop1;scoop1 = scoop2;scoop2 = new RumRaisin();scoop1 = new Icecream();3. จงวาด diagram ที่แสดงถึงความสมั พันธข องการถายทอดคณุ สมบตั ขิ อง class ท่ีใหน ี้บคุ ลากรผูจ ัดการนกั ศึกษาอาจารยหอ งเรียนอปุ กรณป ระกอยการเรยี น ภาควิชาคอมพิวเตอรธ ุรกิจ วิทยาลยั ฟารอีสเทอรน

บทท่ี 6 การสรา ง class ใหมจ าก class เดมิ และ การถา ยทอดคุณสมบัติ 187เร่ิมตน กบั Java รองอธิการฝายวิชาการ รองอธิการฝายบริหาร บรรณารักษ เจา หนาทกี่ ารเงนิ หวั หนา ฝา ยการเงิน4. เราไดพูดถึงการใช method clone() ในบททเี่ ราพดู ถงึ เรอื่ ง array จง override method clone() เพอ่ื ทําการสราง object ใหมจาก class Shapes ท่ไี ดกลา วไวใ นบทน้ี5. จงเพมิ่ method withdraw() ทีท่ าํ หนาทีใ่ นการถอนเงินออกจากบัญชี ของ class Account ท่ีได กลาวไวใ นบทน้ี ใหเขยี นโปรแกรมทดสอบ6. จาก class Shapes ในบทนี้ class ทไ่ี มไ ดพดู ถงึ และไมม ีการกาํ หนดหนา ที่ใด ๆ เลย คือ class Rectangle จงเขยี น code ท่ที าํ ให class Rectangle นส้ี มบรณู 7. จงออกแบบ class Student ทเ่ี กบ็ ขอมูลของนกั ศึกษาวทิ ยาลัยแหง หนงึ่ โดยใหม ี sub class ที่มีทงั้ นกั ศกึ ษาระดับปริญญาตรี และระดบั ปรญิ ญาโท รวมไปถงึ นกั ศกึ ษาภาคพิเศษ พรอมท้งั เขียน method ในการกาํ หนด และเขาหาขอมลู เหลา น้ี กาํ หนดใหม ี method toString() ในทกุ class สาํ หรบั การแสดงขอมูลของ object ทเ่ี กดิ จาก class น้ัน ๆ ใหเ ขยี นโปรแกรมทดสอบ8. จงออกแบบ class Employee ที่มี sub class เปน TempEmployee และ RegularEmployee โดย กําหนดใหลูกจา งทกุ คนมี ชือ่ และอตั ราจางงานท่คี ดิ เปน จาํ นวน บาท ตอ ชว่ั โมง จงเขียน method ท่ี ทําการคาํ นวณหาคา จา งของลกู จางทกุ คน โดยกําหนดใหการคิดคาจา งของ TempEmployee ขึน้ อยู กับจํานวนช่วั โมงทที่ ํา หากทาํ เกิน 40 ชว่ั โมงใหคดิ คา จางเพ่มิ เปน หนึ่งเทา ครง่ึ ของอตั ราจางประจาํ ของจาํ นวนชัว่ โมงทที่ ําเกนิ สว นลกู จา งประจํา (RegularEmployee) จะไดค า จา งตามอตั ราทไ่ี ดต กลง ไวลวงหนา โดยไมคาํ นึงถึงจาํ นวนชั่วโมงของงานทท่ี ํา จงใชเ ทคนคิ ของ polymorphism ในการ ออกแบบ ใหเ ขยี นโปรแกรมทดสอบ * class Employee ควรเปน abstract class9. จงปรับปรงุ class Shapes หรอื sub class ทมี่ าจาก Shapes ใหม ี method ในการสราง object จาก class หน่งึ ใหเ ปน object จากอีก class หนึ่ง ดงั เชนทท่ี าํ เปนตัวอยางในการสราง object Circle จาก Square จงเขยี นโปรแกรมทดสอบ ภาควิชาคอมพิวเตอรธ รุ กจิ วิทยาลยั ฟารอ ีสเทอรน

ในบททเี่ จด็ นเ้ี ราจะพูดถงึ การใช และการออกแบบ exception หรือท่เี รยี กวา การควบคุมและดกั จับ errorทอี่ าจเกดิ ขนึ้ ในการ compile และ run โปรแกรมหลงั จากจบบทนี้แลว ผูอา นจะไดทราบถึง o ความหมายของ exception o วธิ กี ารใชแ ละควบคุม exception o การใช throws และ try o การออกแบบ และใช exception ทเ่ี ขยี นข้นึ เองในภาษา Java น้นั exception เปนการบอกถึงส่งิ ผดิ ปรกติทเ่ี กิดขึน้ ในโปรแกรม ซึง่ อาจเปน error หรือเหตุการณท ไ่ี มค อยเขา ทาทตี่ อ งการความดูแลเปนพิเศษ โดยทั่วไปในการเขียนโปรแกรมทด่ี ีนั้น เราจะตอ งตรวจสอบถึงเหตกุ ารณท ่อี าจทําใหโปรแกรมของเราลมเหลวในการทาํ งาน เชน ขอ มูลถกู หารดวยศูนย เขา หาขอ มลู ใน array ดวยการใช index ทไ่ี มมีอยจู รงิ หรือ อา งถึงหนวยความจาํ ท่ีเปน null เปน ตนถงึ แมวา เรามีวิธกี ารตรวจสอบ error ตา ง ๆ เหลา นด้ี ว ยการใช if-else หรือ การตรวจสอบอืน่ ๆ ที่ทําใหโปรแกรมของเราทาํ งานไดร าบร่ืน แตจ ะทําให code ของเราดแู ลว วุนวายเพราะถา มกี ารตรวจสอบ errorมาก code ของเรากจ็ ะดซู ับซอนมากย่ิงขน้ึ แตไ มไ ดหมายความวา เราจะไมต รวจสอบ และดกั จบั errorเหลาน้ี การนาํ เอา exception เขา มาเปน ตวั ชว ยในการตรวจสอบและดักจบั ทาํ ใหเ กิดการแยกสว นของcode ทท่ี ํางานไดร าบรื่น ออกจากสวนของ code ทจี่ ัดการเกีย่ วกบั error ทําใหเราสามารถท่จี ะคนหาสว นของ code ทัง้ สองไดง ายขึ้น ถามีการเปลย่ี นแปลง code ในอนาคต ขอดีอกี อันหนง่ึ ของ exception กค็ อืทําใหการตรวจสอบและดกั จับเปน ไปอยางเฉพาะเจาะจง ตรงกับ error ทเี่ กดิ ขึ้น ทาํ ใหการแกไ ขเปนไปอยา งถกู ตอง และเนอื่ งจากวา error มหี ลากหลายรูปแบบ เราตอ งเขียน code ข้ึนมารองรบั ไมเ ชน นน้ั แลวโปรแกรมของเราก็จะไมผ านการ compileเราไมจ ําเปน ทจ่ี ะตอ งใช exception ในการตรวจสอบและดักจบั error ในโปรแกรมเสมอไป เพราะการใชexception จะเสยี คาใชจายในการประมวลผลมาก ทําใหโ ปรแกรมทาํ งานชา ลง ดงั นนั้ เราจะตอ งตัดสนิ ใจใหด วี า ควรจะใช exception ในกรณไี หน อยา งไร ตัวอยา งของโปรแกรมท่ไี มต องใช exception ก็นา จะเปน การใสข อ มลู นาํ เขาแบบผดิ ๆ ของ user ซง่ึ ถือเปน เร่อื งปกติ ถาเรามวั แตเ สยี เวลาในการดกั จบั ดวยการใช exception แทนการตรวจสอบและดักจบั ทวั่ ไปโปรแกรมของเราก็จะเสยี เวลาในการประมวลผลสวนอน่ื ๆ ไปการใช exception ใน Java นัน้ จะโดยทั่วไปจะเปน การโยน (throw) การจดั การ error ทีเ่ กิดขนึ้ ใหกับสว นของ code ทท่ี าํ หนาท่ีในดา นการจดั การกบั error นั้น ๆ ท่เี กิดข้นึ ซง่ึ code สวนน้จี ะคอยดักจบั(catch) ถา มกี ารโยนเกิดขึน้ แตไ มจ าํ เปน ที่ code สว นน้ีจะตองแกไข error ท่ีเกิดขึน้ อาจเปนเพียงการดกัจบั เทานน้ั เพื่อใหโ ปรแกรมทาํ งานตอไปไดเทา น้ันเราคงไมพดู ถึงขอมูลตา ง ๆ ทเ่ี กี่ยวกบั error และ exception มากนกั แตจะเนนการใช exception ในการตรวจสอบและดกั จับ error แบบพอประมาณ ผทู ส่ี นใจกส็ ามารถที่จะหาอานไดจ ากหนังสอื Java ทัว่ ๆ ไปหรอื ใน web sit ของ Java เองException โดยปกติจะเปน object จาก sub class (class ใด class หนง่ึ ) ของ class Throwable ท่ีJava มีให และ class หลัก ๆ สอง class ทเ่ี กดิ จาก class Throwable โดยตรงท่ีเปน class หลักของclass ทเ่ี ปน class เฉพาะของการจัดการกับ error คอื class Error และ class Exception (ภาพที่ 7.1)

บทท่ี 7 การตรวจสอบและดกั จบั error (Exceptions) 189เร่ิมตน กบั Java Throwable Error Exception Other sub classes Other sub classesภาพที่ 7.1 Class Throwable และ sub classesโดยการออกแบบของ Java เราไมค วรทจ่ี ะ catch error ทเี่ กิดขึน้ จากการตรวจสอบของ class Errorเพราะ error ทเ่ี กิดขน้ึ จะเปน error ท่ี โดยทว่ั ไปจะไมเ กิดขนึ้ (หรอื ไมคาดวาจะเกดิ ) ซ่งึ มอี ยูส าม classคือ ThreadDeath LinkageError และ VirtualMachineError เราคงจะไมเขาไปวนุ วายกับ class ทัง้ สามเพราะวา เราไมส ามารถทจ่ี ะแกไ ข error ท่เี กิดขนึ้ นีไ้ ดโดยตรง และตอ งใชก ารตรวจสอบอยา งละเอยี ดกบัerror ท่เี กิดขึ้น (แตคงตอ งหวงั ในใจวา error ท่วี าคงไมเ กิดขน้ึ กบั เรา)เราจะมาดูตวั อยางการใช exception ในการจดั การกบั error ทเี่ กิดขึ้นในโปรแกรมของเรา ดว ยโปรแกรมตัวอยางตอ ไปน้ี//ThrowException.javaclass ThrowException { public static void main(String[] args) throws Exception { int number = 10; int divider = 0; System.out.println(\"Divide \" + number + \" by \" + divider); int result = number / divider; System.out.println(\"Result is \" + result); }}โปรแกรมตวั อยา งดา นบนนท้ี าํ การ throw exception ซ่งึ เปน exception ทีเ่ กดิ ขนึ้ ในขณะท่ีโปรแกรมกาํ ลงั ไดร บั การประมวลผล (เชน การหารตวั เลขที่เปน int ดว ย 0 – เราตง้ั ใจให error น้ีเกดิ ข้ึน) โปรแกรมตวั อยางของเราไมไ ดทําการดกั จบั ใด ๆ ทาํ แตเ ฉพาะการตรวจสอบ error ท่เี กิดขน้ึ เทา นน้ั ดังที่เหน็ จากผลลพั ธข องการ run น้ีDivide 10 by 0java.lang.ArithmeticException: / by zero at ThrowException.main(ThrowException.java:10)จะเหน็ วา Java จะฟอ งใหเรารวู า error ท่ีเกดิ ขึน้ เปน error ชนดิ ไหน (ArithmeticException) ที่พยายามหาร int ดวย 0 พรอ มกับบอกวาเกิดขึน้ ในบรรทดั ที่เทา ไร หลังจากนน้ั กย็ ตุ กิ ารทาํ งานถา หากวา เราตอ งการทจ่ี ะแกไ ข หรอื ทําการใด ๆ สักอยางหน่ึงกับ error ทเี่ กิดขน้ึ เราตองใช try และcatch ดังตวั อยา งตอไปน้ี ภาควิชาคอมพิวเตอรธรุ กิจ วิทยาลัยฟารอีสเทอรน

บทที่ 7 การตรวจสอบและดกั จับ error (Exceptions) 190เร่มิ ตน กับ Java//TryAndCatchExample1.java//adopted from Ivor Horton'sclass TryAndCatchExample1{ public static void main(String[] args) { int number1 = 15; int number2 = 0; try { System.out.println(\"Try to divide by zero in a try block.\"); int result = number1 / number2; System.out.println(\"Leaving a try block.\"); } catch(ArithmeticException ex) { System.out.println(\"Exception caught in a catch block.\"); } System.out.println(\"After a try block.\"); }}โปรแกรม TryAndCatchExample1.java เปนโปรแกรมตัวอยา งการใช try และ catch ในการจดั การกบัการหาร int ดว ย 0 (เราจะไมใ ชการ throws exception เหมอื นกบั ตัวอยางแรก) เรากําหนดให number1มีคา เปน 15 และ number2 มคี า เปน 0 พรอ มทง้ั กําหนดใหresult = number1 / number2;ใน block ของ try ซง่ึ ประโยคดงั กลาวจะทาํ ใหเ กิดการโยน exception ไปยัง block ของ catch และในblock ของ catch เราจะดักดว ย exception ที่ชื่อ ArithmaticException เราไมไ ดท าํ อะไรมากมายไปกวาการแสดงขอความวา มกี ารดักจบั error ผลลพั ธท ไี่ ดจากการ run คือTry to divide by zero in a try block.Exception caught in a catch block.After a try block.จากผลลัพธท่ไี ด code ทไ่ี ดร บั การประมวลผลคือ ประโยคทอ่ี ยูใ น block ของ try 2 ประโยคแรกโดยเฉพาะประโยคทสี่ อง ท่ีทาํ ใหก ารประมวลกระโดดไปยัง block ของ catch ทําใหป ระโยคทสี่ ามไมไดรบั การประมวลผล และหลังจากที่ประมวลผลประโยคท่ีอยูใน block ของ catch แลว การประมวลผลประโยคสดุ ทายทต่ี ามหลัง block ของ catch จึงเกิดข้นึเราสามารถใช ตัวแปร ex ท่เี ราไดประกาศใน parameter list ของ method catch() แสดงถงึ ขอความที่บงบอกเก่ียวกับ error ทีเ่ กดิ ขึ้น ดว ยการเพม่ิ ประโยคตอไปน้ีใน block ของ catchSystem.out.println(ex.getMessage());ex.printStackTrace();ประโยคแรกเรียกใช method getMessage() ทเ่ี กิดขนึ้ ทาํ การแสดงผลไปยงั หนาจอ สว นประโยคทสี่ องเปนการตรวจสอบถึงทม่ี าของ error ท่เี กิดข้นึ ดังทแ่ี สดงใหเห็นจากการ run โปรแกรมอกี คร้ังหลังจากการเปลย่ี นแปลง code ใน block ของ catchTry to divide by zero in a try block.Exception caught in a catch block./ by zerojava.lang.ArithmeticException: / by zero ภาควิชาคอมพิวเตอรธ ุรกจิ วทิ ยาลยั ฟารอ สี เทอรน

บทท่ี 7 การตรวจสอบและดักจบั error (Exceptions) 191เรม่ิ ตนกับ Javaat TryAndCatchExample1.main(TryAndCatchExample1.java:11)After a try block.เราไมจาํ เปนทจ่ี ะตองแสดงผลท่เี กิดขน้ึ ไปยงั หนาจอ สวนใหญแลว ขอมูลเหลานีจ้ ะเปนประโยชนต อ การตรวจสอบถงึ error ทเ่ี กิดขน้ึ เทานั้นเอง ส่ิงทส่ี ําคญั ที่เราตองกังวลกค็ อื การตรวจสอบและดักจับ error ที่อาจเกิดข้นึJava กาํ หนดให try และ catch เปนของคกู นั เราไมส ามารถทจี่ ะแยก block สองออกจากกนั ได ถา เรากาํ หนดใหม ปี ระโยคอะไรก็ไดส กั ประโยคหนงึ่ ระหวาง block ของ try และ catch โปรแกรมของเราจะcompile ไมผ าน ดงั ตวั อยา งทม่ี ีการเพม่ิ ประโยคระหวา ง block ท้งั สองนี้ … … System.out.println(\"Leaving a try block.\");}System.out.pritnln(\"In between try and catch blocks.\");catch(ArithmeticException ex) { … …ถา เรา compile เราจะได error ดงั ทเี่ หน็ น้ีTryAndCatchExample1.java:9: 'try' without 'catch' or 'finally' try { ^TryAndCatchExample1.java:15: 'catch' without 'try' catch(ArithmeticException ex) { ^2 errorsตัวอยา งการใช try และ catch ที่ classic อกี อันหนึ่งก็คือ การใช try และ catch ใน loop ดังตัวอยางตอไปนี้//TryAndCatchExample2.java//adopted from Ivor Horton'sclass TryAndCatchExample2 { public static void main(String[] args) { int number = 10; for(int index = 5; index >= -1; index--) try { System.out.println(\"try block: index = \" + index); int result = number / index; System.out.println(\"Leaving a try block.\"); } catch(ArithmeticException e) { System.out.println(\"Exception caught in a catch block.\"); System.out.println(e.getMessage()); e.printStackTrace(); } } System.out.println(\"After a try and catch blocks.\");} ภาควิชาคอมพิวเตอรธรุ กิจ วทิ ยาลยั ฟารอ สี เทอรน

บทท่ี 7 การตรวจสอบและดักจบั error (Exceptions) 192เริม่ ตน กับ Javaกอนท่ีจะอธิบายถึงการทาํ งานของตวั โปรแกรม เรามาดผู ลลพั ธท ไี่ ดจ ากการ runtry block: index = 5Leaving a try block.try block: index = 4Leaving a try block.try block: index = 3Leaving a try block.try block: index = 2Leaving a try block.try block: index = 1Leaving a try block.try block: index = 0Exception caught in a catch block./ by zerojava.lang.ArithmeticException: / by zero at TryAndCatchExample2.main(TryAndCatchExample2.java:11)try block: index = -1Leaving a try block.After a try and catch blocks.ประโยคใน block ของ try จะถกู ประมวลผลจนกวา คา ของ index จะเปน 0 จึงจะกระโดดไปประมวลผลประโยคทอี่ ยูใน block ของ catch หลังจากนน้ั ก็กลับไปประมวลผลประโยคที่เหลอื อยใู น block ของ tryและประโยคทอี่ ยทู ายสดุ ในโปรแกรม อกี ประโยคหน่งึจะเหน็ ไดว า เรามที างเลือกอยสู องทางในการจัดการกบั error ทางแรกคอื ยตุ ิการทาํ งาน (terminate)ของโปรแกรม หรอื code สว นนนั้ ๆ ท่ที ําใหเกิด error หรอื ทางท่ีสอง ซึง่ เปนทางเลอื กทที่ าํ ใหโ ปรแกรมหรอื code สว นน้ัน ๆ กลบั ไปรับการประมวลผลใหม (resumption) ทั้งสองวิธีเปน การตรวจสอบและดักจบัerror ทีด่ พี อกัน ทั้งน้กี ็ข้ึนอยกู บั ลักษณะของงานทท่ี าํ อยู ลองมาดตู วั อยา งอีกสักตวั หนึง่ ในการใช classNumberFormatException ในการดักจับ error//NumFormatException.javaimport java.lang.Integer;class NumFormatException { public static void main(String[] args) { int inputNum, sum = 0; //reading input from argument list //only those in [0..9] for(int i = 0; i < args.length; i++) { try { inputNum = Integer.parseInt(args[i]); sum += inputNum; } //ignore input that's not a number catch(NumberFormatException e) { e.printStackTrace(System.out); } } System.out.println(\"Sum is \" + sum); }}เรากําหนดใหโ ปรแกรมของเรารบั ขอมูลจาก command line argument ซึง่ เปน วิธีการทยี่ อมใหผ ใู ชใ สขอมูลตามหลังชือ่ ของโปรแกรม (ดูจากผลลพั ธก าร run) เราจะทาํ การหาผลรวมของตัวเลขเหลา น้ัน ภาควิชาคอมพิวเตอรธ รุ กิจ วิทยาลัยฟารอีสเทอรน

บทที่ 7 การตรวจสอบและดกั จบั error (Exceptions) 193เรมิ่ ตนกับ Javaทงั้ หมดจนกวา ผูใชจ ะพอใจ คอื กดปุม <enter> หลงั จากใสข อ ความจนพอใจ ใน catch block เราดักจบัดวย NumberFormatException ซง่ึ จะไมย อมรบั ขอมลู นาํ เขา ทีไ่ มใชต วั เลขที่เปน int และทุกครัง้ ท่เี จอขอมลู แบบนโ้ี ปรแกรมจะสง รายละเอียดไปใหผ ูใ ช และจะหาผลรวมของขอมูลทถี่ กู ตองน้ัน ดงั ที่แสดงไวดา นลา งน้ี>java NumFormatException 1 2 3 4 p 5 6java.lang.NumberFormatException: For input string: \"p\" atjava.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:426) at java.lang.Integer.parseInt(Integer.java:476) at NumFormatException.main(NumFormatException.java:12)Sum is 21ในการสราง block สําหรับการ catch error ทีเ่ กิดข้ึนเราไมจ ําเปน ท่จี ะตอ งมี catch block เพยี ง blockเดียว เราอาจมมี ากกวาหน่ึง catch block ไดแ ตมขี อ แมว า การ catch exception ตองทําจาก sub classออกไปหา super class มฉิ ะนนั้ แลว การดกั จบั ในหลาย ๆ block อาจไมเ กดิ ข้ึน เชนtry { … …}catch(Exception e) { … …}catch(ArithmeticException ex) { … ..}เนอ่ื งจากวา class ArithmeticException เปน class ทีเ่ กดิ มาจาก class Exception ดังนนั้ error ที่เกิดขึน้ กจ็ ะถกู ดักจบั ใน catch block ทัง้ หมด การดักจบั ใน catch block ทส่ี องจึงไมเ กิดข้ึนเรามาลองดตู ัวอยางการดักจบั error ในรปู แบบน้กี ันดู//MultipleCatches.javaclass MultipleCatches { public static void main(String[] args) { //force divide by zero at index = 2 int []number = {1, 2, 0, 4}; int num = 12; //force array index out of bound at index = 4 for(int i = 0; i < number.length + 1; i++) { try { num /= number[i]; System.out.println(\"result = \" + num); } catch(ArithmeticException e) { System.out.println(\"error message: \" + e.getMessage()); e.printStackTrace(); } catch(ArrayIndexOutOfBoundsException e) { ภาควิชาคอมพิวเตอรธุรกิจ วิทยาลัยฟารอ ีสเทอรน

บทที่ 7 การตรวจสอบและดกั จบั error (Exceptions) 194เรมิ่ ตนกับ Java System.out.println(\"error message: \" + e.getMessage()); e.printStackTrace(); } } System.out.println(\"After a for loop.\"); }}เราตองการทจี่ ะบงั คบั ใหเ กิด error สองอยา งคอื หารดวยศนู ย และเขา หา index ของ array ท่ีไมม อี ยูจริง โดยเรากําหนดใหขอ มูลท่ี index = 2 มีคาเปนศนู ย และให for loop ทํางานเกินไปหนง่ึ ครั้ง การ runโปรแกรมตวั อยา งของเราทําใหเกิด ผลลพั ธด งั นีค้ อืresult = 12result = 6error message: / by zerojava.lang.ArithmeticException: / by zero at MultipleCatches.main(MultipleCatches.java:11)result = 1error message: 4java.lang.ArrayIndexOutOfBoundsException: 4 at MultipleCatches.main(MultipleCatches.java:11)After a for loop.จะเห็นวา โปรแกรมของเราดักจับ error ไดตามทเ่ี ราตง้ั ใจไว การหารดวยศนู ย และการอา งถึง index ของarray ท่ีไมมีอยจู ริง ถกู ดกั ไวท ้ังสองตวั ถาเปนการจดั การท่เี ปน การพฒั นาโปรแกรมจริง ๆ เราคงทําแคการดกั จับไมได คงตอ งมกี ระบวนการอ่นื ๆ ในการทาํ ใหโ ปรแกรมทาํ งานไดอ ยางราบรน่ื และกระบวนการจัดการกบั error ที่เกิดขน้ึ ก็ตองมีความซบั ซอ นเพม่ิ ข้ึนJava ยังมี block อีก block หน่ึงทีเ่ อาไว catch error ทีเ่ กิดขนึ้ ทซี่ ่ึงเปน block สุดทา ยของการ catchทงั้ หมด โดยกาํ หนดให block นีท้ ีชอื่ วา finallyFinally เปน การดักจับ error สุดทายของการดักท้งั หมด ดงั น้นั finally จะอยูทอ่ี น่ื ไมไ ดน อกจาก blockสดุ ทายของ catch block ทั้งหมด เราจะแสดงใหด ู ดวยการนาํ เอา finally ไปใสไวเปน block สดุ ทา ยในตัวอยางกอ นหนาน้ี ดังน้ี … …}catch(ArrayIndexOutOfBoundsException e) { System.out.println(\"error message: \" + e.getMessage()); e.printStackTrace();}finally { System.out.println(\"In finally block.\");} … …finally block ทเี่ ราใชจะถกู ประมวลผลเสมอ ไมว า อะไรจะเกิดขึ้นก็ตามใน block อ่นื ๆ กอนหนา ดงัตวั อยา งของผลลพั ธท แี่ สดงใหดบู างสว นนี้ … ภาควิชาคอมพิวเตอรธรุ กจิ วิทยาลยั ฟารอ สี เทอรน

บทที่ 7 การตรวจสอบและดักจับ error (Exceptions) 195เร่มิ ตน กบั Java … at MultipleCatches.main(MultipleCatches.java:13)In finally block.After a for loop.โดยทัว่ ไปหนาท่ีหลกั ของ finally จะเปนการเกบ็ กวาด code ทโี่ ปรแกรมตองการประมวลผล (เชน การปดเปดไฟล) กอ นออกจาก ตวั method main() และกลับออกไปสูร ะบบในท่ีสดุ//ThrowsWithTry.javaimport java.io.*;import java.lang.Integer;class ThrowsWithTry { public static void main(String[] args) throws IOException { BufferedReader buffer; InputStreamReader isr; String input; int first, divider; //keep looping until error occur while(true) { System.out.print(\"Enter a number: \"); isr = new InputStreamReader(System.in); buffer = new BufferedReader(isr); //get first number input = buffer.readLine(); first = Integer.parseInt(input); //get second number System.out.print(\"Enter a divider: \"); input = buffer.readLine(); divider = Integer.parseInt(input); try { double result = first / divider; System.out.println(\"Result = \" + result); } catch(ArithmeticException e) { System.out.println(\"Exception: \" + e.getMessage()); e.printStackTrace(); } } }}โปรแกรม ThrowsWithTry.java เปน โปรแกรมทตี่ อ งการแสดงการใช throws และ try – catch ควบคกู นัโดยตวั โปรแกรมเองจะทาํ การอานขอ มูลสองตัวจาก keyboard ซ่ึงกาํ หนดใหขอมูลทงั้ สองตวั เปน intและจะทาํ การหาผลลัพธของการหารขอมลู ตัวแรก ดว ยขอ มลู ตัวทสี่ องโปรแกรมจะหยดุ การทํางานกต็ อ เมื่อผใู ชใสขอ มูลที่ไมใ ชต วั เลข และจะทาํ การฟอ งถา ขอมลู ตัวทส่ี องของการหารมีคา เปน ศูนย ผลลัพธท ่ีไดจ ากการ run คือEnter a number: 23Enter a divider: 5Result = 4.0Enter a number: 56 ภาควิชาคอมพิวเตอรธุรกจิ วทิ ยาลยั ฟารอสี เทอรน


Like this book? You can publish your book online for free in a few minutes!
Create your own flipbook