object and classes
DESCRIPTION
Object and classes. บทนี้เรียนอะไรบ้าง. แนะนำ Object-oriented programming บอกวิธีการสร้าง object จากคลาสที่จาวาให้มา สอนวิธีสร้างคลาสของเราเอง. แนะนำ Object-Oriented Programming. โปรแกรมประกอบขึ้นจากออบเจ็กต์ แต่ละออบเจ็กต์จะมีฟังก์ชั่นให้เรียกใช้ - PowerPoint PPT PresentationTRANSCRIPT
Object and classes
บทนเรยนอะไรบาง• แนะนำา Object-oriented programming• บอกวธการสราง object จากคลาสทจาวาใหมา• สอนวธสรางคลาสของเราเอง
แนะนำา Object-Oriented Programming
• โปรแกรมประกอบขนจากออบเจกต• แตละออบเจกตจะมฟงกชนใหเรยกใช– คนเรยกใชไมจำาเปนตองรวาขางในออบเจกตทำางานยงไง
– ขอใหใชไดตามทตองการกพอ• วธคดในการโปรแกรม– เมอตองการแกปญหา ใหออกแบบตวขอมลทตองใชกอน
– แลววธแกปญหาคอยตามมา
คลาส• คลาสคอ template ทเราจะใชสรางออบเจกต– พดงายๆ มนเปนตวกำาหนดวา ออบเจกตทสรางจาก
มน จะมขอมลอะไรอยภายในบาง– คลาสเปรยบเสมอนแมพมพ สวนออบเจกตกเปนสงทแมพมพพมพออกมา
• เมอเราสรางออบเจกตขนจากคลาส– เราเรยกเหตการณนวา การสราง instance ของคลาส
• ภายในแตละออบเจกต– ขอมล หรอดาตา เราเรยกวา instance fields หรอ
instance variables• แตละออบเจกต จะมคาของแตละ instance field เปนของตนเองไมใชคารวมกบออบเจกตอน• สถานะของคาตวแปรเหลานทงหมด ถอเปน state ของออบเจกต• ซงเมอเรยกเมธอด state ของออบเจกตอาจเปลยนได
– สวนฟงกชนทออบเจกตนนเรยกเพอจดการขอมลขางตน เรยกวา methods
• หามเขาถงคาของ instance field โดยตรง• ตองอาน และเขยนคาตวแปร จากเมธอดเทานน• ทงนเพอ– ปองกนการยดคาผดๆ ใสลงไปใน instance field• เชน a.x = 100; จรงๆ x อาจจะมคาเกน 99 ไมได ดงนนเขยนเมธอดคมดกวา
– เวลาจะเปลยนพฤตกรรมการทำาอะไร จะไดแกในเมธอด ทเดยว ไมตองมาแกหลายๆท
•
extends
• ถาเราสรางคลาสใหม โดยใชการ extends จากคลาสเกา– คลาสใหมจะไดรบ ตวแปร และเมธอด มาจากคลาสเกาทงหมด
– เราแคเขยนตวแปรกบเมธอดเพม ทคลาสใหมจะม เทานน กพอ
• การ extends นน ใชหลกของการ inheritance ซงจะสอนในบทตอไป
Relationship between classes• แตละคลาส สมพนธกนยงไงไดบาง• Dependence (uses-a)– คลาส A จะ depend on คลาส B ถาคลาส A มการใชออบเจกตของคลาส B
• Aggregation (has-a)– ออบเจกตในคลาส A สามารถเกบ ออบเจกตในคลาส B ได นเรยกวาเปน
aggregation• Inheritance (is-a)– Car extends จาก Vehicle– Car จะถอวา เฉพาะเจาะจง หรอ specialise กวา สามารถทำาสงท Vehicle
ทำาได และกทำาอยางอนไดเพมเตมดวย– Car is a Vehicle แตวา Vehicle ไมจำาเปนตองเปน Car
การวาดความสมพนธ• เดยวนใช UML Diagram– ปกต คลาสจะวาดดวยสเหลยม– ความสมพนธจะวาดเปนเสนตางๆกนไป– ไปลองใช ArgoUML (http://argouml.tigris.org) หรอ
Violet (http://violet.sourceforge.net)
การใชงานคลาสทจาวาสรางไวแลว• จะใชงานออบเจกตไดนน ตอง– สรางออบเจกต– กำาหนดคาตางๆสำาหรบขอมลภายในออบเจกต– ใชงานโดยการเรยกเมธอดทใชกบออบเจกตนนได
(แนนอนวาตองนยามเมธอดกอน)
มา zoom ดทการสรางออบเจกตDate x = new Date();
จงกอเกดตวตน
คอนสตรคเตอร เปนตว บอกชนดของออบเจกต และเรยกโคดมารนเพอ
initialize ตวออบเจกตนนดวย
พอสรางเสรจกใชงานได• เชนเอาไปปรน ( แตตองนยาม toString() กอน
เพราะจาวา ปรนออบเจกตไมเปน เราตองบอกมนวาจะปรนยงไง)– System.out.println(new Date()); หรอ– String s = new Date().toString();
ตรงนเปนการเอาออบเจกตทสรางขนมา ไปเรยกเมธอด toString() ในทนท แต
จรงๆเราเรยกจากตวแปรกได
ซงควรใชตวแปร ถาจะเกบออบเจกตไวใชตอ
สภาพ ณ เวลาตางๆ• Date x
• เมอยงไมมตวตนออบเจกต จงเรยกเมธอดไมได– ฉะนนคำาสง s = x.toString(); จง error
x มตวแปร x ซงสามารถชไปทออบ
เจกตทเปนไทป Date ไดแตยงไมมตวออบเจกตทจะใหช
เลย
• ดงนนตองสรางออบเจกตใหมตวตน เพอเอา x ชไปทออบเจกตนน
• มทางเลอกสองทาง– ใชคอนสตรคเตอร: x = new Date();– ทำาตวแปรใหชไปทตวแปรอนทเคยสรางออบเจกตสมบรณมากอนแลว: x = birthday;
• Date x = new Date();
• ถาเราทำาตอจากขางบนน โดยเขยนวา Date x2 = x;
xDate
ตวแปร เปนpointer โยงไปยงกอนออบเจกตทแทจรง
xDate
X2 จะเหนวา ตวแปรสองตวจะชไปท กอนออบเจกตเดยวกน ดงนนถา
เปลยน Date object ตวน จาก x กจะเหนความเปลยนแปลงถาด
จาก x2 ดวยเหมอนกน
• เราสามารถบอกตวแปรวา ไมใหชไปไหน กได– X = null;
• สามารถใช null ในการตรวจสภาพออบเจกตได– if (x != null){ }
• แตอยาลมวา ถาตวแปรไหนเปน null แลว จะเรยก เมธอดใชไมได error หมด
ตวอยางคลาส• Date– ออบเจกตไทปน เปนขอมลจดหนงของเวลา– มเมธอดใหเราเปรยบเทยบกบ Date อน วา Date ไหน
มากอนมาหลง เชนif(today.before(birthday))
System.out.println(“Have some time left.”);
• GregorianCalendar– Extends มาจาก Calendar ทนยามปฏทนอยางทวไป– มเมธอดเยอะ มคอนสตรคเตอรหลายตว เชน new GregorianCalendar() ซงสรางออบเจกตทเกบวนเวลา ณ ตอนสราง
new GregorianCalendar(1999, 11, 31) ซงสรางออบเจกตทเกบ ขอมล เวลาเทยงคน วนท 31 ธค 1999 ( เดอน เรมนบเดอนแรกทเลข
0) หรอวาจะใชคอนสตรคเตอรทละเอยดกวา ทกำาหนดเวลาไดดวย กได
สงเกต วาเราไมจำาเปนตองรวาขางในเกบวนเวลา เดอนป ยงไง แคเรยกใชเมธอดไดกพอ
Mutator and accessor methods
• จะจดการกบคาตางๆทเกบไว จากตวอยาง Date ไดตอง
• อานได และเขยนได• สำาหรบการอานคา ใช accessor methods ( หมายถงเมธอดทใชอานคาตางๆในออบเจกต) ตวอยางเชน
// construct d as current date GregorianCalendar d = new GregorianCalendar();
int today = d.get(Calendar.DAY_OF_MONTH); int month = d.get(Calendar.MONTH);
• การเปลยนคาตางๆภายในออบเจกต ใช mutator methods (เมธอดทใชสำาหรบเปลยนคา) ตวอยางเชน
d.set(Calendar.DAY_OF_MONTH, 15);d.set(Calendar.YEAR, 2001);d.set(Calendar.MONTH, Calendar.APRIL);
ทงนขนกบวาคลาสนนมเมธอดอะไรใหเปลยนคาของขอมลบาง อยางคลาสปฏทน น มเมธอดทชวยเลอนวนเวลา ดวย คอ
d.add(Calendar.MONTH, 3); เปนการเลอนวนเวลา ของ d ออกไปสามเดอน
• โดยปกตแลว accessor จะมคำานำาหนาวา get สวนmutator จะมคำานำาหนาวา set ตวอยางเชน
Date time = calendar.getTime();
calendar.setTime(time);
เอาคาวนเวลา (ทเปน ชนด Date) ออกจาก
ปฏทน มาเกบไวใน ตวแปร time สมมตวาออบเจกตน
มอยแลว เปนชนดCalendar นะ
เซตเวลา ของcalendar object
ตวอยางเพมเตม• รวนเดอนป และตองการสราง Date ทแทนวนเดอนปนน– ตอนน Date ไมมเมธอดททำาได จงตองใช calendar ชวยGregorianCalendar cal = new GregorianCalendar(year, month,
day);Date hireDay = calendar.getTime();
• ม Date object อย ตองการหาคาตางๆจาก Date object นนGregorianCalendar cal = new GregorianCalendar();Cal.setTime(hireDay);int year = cal.get(Calendar.YEAR);
ตวอยางโปรแกรม วาดปฏทนของเดอนน
• calendar
การนยามคลาสไวใชเอง• คลาสทเราจะนยามจากนไป ไมจำาเปนตองม main• แตจะม field กบเมธอด• การเขยนโปรแกรม จะเกดจากการใช main
method ของคลาสหนง เรยกใชเมธอดของคลาสอนๆ
• เดยวลองมาดคลาสสำาหรบเกบขอมลลกจาง เอาไวใชกบการจายเงนเดอนด
class Employee{//constructorpublic Employee(String n, double s, int year, int month, int day){name = n;salary = s;GregorianCalendar calendar = new GregorianCalendar(year, month-1, day);hireDay = calendar.getTime();}
//methodpublic String getName(){return name;}
… //instance fields
private String name;private double salary;private Date hireDay;
ตวอยางโปรแกรมทใชงาน Employee• EmployeeTest
• ใชงานจรงๆแคสรางอาเรยแลวเตมรายละเอยดลกจางสามคนลงไป• จากนนลปเพมเงนเดอนทกคน คนละ 5%• แลวพมพรายละเอยดของทกคนออกมา
– อนนเรยกเมธอดหลายอน เพอใหไดขอมลทกสวน• สงเกต
– วา main จะอยใน EmployeeTest เทานน– ชอไฟลจะตองตรงกบชอคลาสทเปน public – ในหนงไฟลม public class ไดแคอนเดยว แตนอกนนจะมกคลาสกได– ตอนคอมไพล มนจะแยกไฟล .class ให– เวลารน ตองรนคลาสทม main เสมอ
• ถาเราแยกไฟลแตแรก ตอนคอมไพล สามารถใชjavac Employee*.java เพอคอมไพลทกไฟลได
หรอ เรยกJavac EmployeeTest.java
จาวาจะคอมไพล EmployeeTest เมอมนเหนวา มการใชEmployee ภายใน มนจะไปหา Employee.class ซงถาหาไมเจอ
มนจะคอมไพลจาก Employee.java ใหเอง
นอกจากน ถงหาเจอ แตไฟล .class นนเกากวา .java ทม มนกจะคอมไพลใหมใหเหมอนกน
มาด Employee กนอยางละเอยดหนอย
• สงเกตไดวา– ทกเมธอดเปน public นนคอ เมธอดทกเมธอดในทกคลาสสามารถเรยกเมธอดเหลานได
– ทกตวแปรเปน private นนคอ เมธอดทอานคาจากตวแปร เหลานไดโดยตรงจะตองเปนเมธอดจากคลาส Employee เทานน
• ไมควรใหตวแปรเปน public เพราะสวนไหนของโปรแกรมจะมาเปลยน ขอมลกได เปลยนอยางไรกได อาจจะมการกระทำาตองหามทเราไมทน
คด เกดขนได– ตวแปร สองตว กเปนออบเจกต name เปน String สวน
hireDay เปน Date• ใชแลว ออบเจกตสามารถใสออบเจกตอนๆ ซอนๆกนได
constructors
public Employee(String n, double s, int year, int month, int day)
{ name = n; salary = s; GregorianCalendar calendar = new
GregorianCalendar(year, month - 1, day); // GregorianCalendar uses 0 for January hireDay = calendar.getTime(); }
ชอตองเหมอนชอคลาส คอนสตรคเตอรใชเซตคาภายในออบ
เจกตทพงถกสราง ใหเปนไปตามทเราตองการ
คอนสตรคเตอรไมรเทรนคา
new Employee(“James Bond, 100000, 1950, 1, 1); จะได object ของคลาส Employee ทมขางในเปน
คอนสตรคเตอร เรยกใชไดพรอม new เทานน ดงนนจะไมสามารถใชกบออบเจกตทถกสรางขนแลวได
name = “James Bond”Salary = 100000;
hireDay = January 1, 1950
ขอควรระวง• อยาให local variable มชอเดยวกบ field ทเรานยามไว
public Employee(String n, double s, int year, int month, int day)
{ String name = n; double salary = s; จะกลายเปนใหคากบ local
variable ไป ไมไดใหคาอะไรกบfields
Implicit and explicit parametersจากpublic void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; salary += raise; }
ถาเราเรยกEmployee number007 = new Employee(“James Bond, 100000,
1950, 1, 1);number007.raiseSalary(5);
Implicit parameter Explicit parameter
• ซงโคดทรนไป จะเหมอนกบไดทำาdouble raise = number007.salary * byPercent / 100; number007.salary += raise;
ซงถาเราอยากใหมการอางถง implicit parameter เราจะ ทำาไดโดยใช คำาวา this ตวอยางเชน ในโคดของคอน
สตรคเตอรเราอาจจะใชdouble raise = this.salary * byPercent / 100; this.salary += raise;
คราวนมาลองดเมธอดในคลาส Employee กนหนอย
public String getName() { return name; }
public double getSalary() { return salary; }
public Date getHireDay() { return hireDay; }
พวกนเปน accessor•name ตองไมเปน public เพราะทางผ
เขยนไมตองการให name ถกเปลยนหลง จากใหชอผานคอนสตรคเตอรไปแลว ดง
นน พอเปน private จงปองกนการถกเปลยนชอได
•salary เปลยนไดกจรง แตถาเปนprivate แบบนจะเปลยนไดดวยraiseSalary เทานน ซงถาเกดอะไรผด
พลาด เรากจะไดไปแกท raiseSalary ท เดยว ถาเปน public แลวละก กวาจะตาม
หาทผดเจอ จะยากมาก
การใชเมธอดในการเปลยนขอมลเทานน มประโยชนจรงๆ
จากตวอยาง Employee ถามการเปลยนรปแบบของชอเปนString firstName;String lastName;
เวลาเราตองการดงชอของ Employee ออกมา เรากทำาแคไปแก getname เทานน อาจแกใหเปน return firstName + “ “ + lastName;
ซงจะไมตองมผลกระทบกบสวนอนของโปรแกรม
นอกจากน เมธอดยงตรวจ error ไปในตวได เชนใหโคดของเมธอดเชคกอน เสมอวา salary ตองไมตำากวา 0 ดงนน เมอบงคบวาตองเรยกเมธอดเพอ
เปลยน salary กจะทำาใหคา salary ไมมวนตำากวา 0 อยางแนนอน
ระวง public Date getHireDay() { return hireDay; }
จรงๆ โคดนไมเวรค เพราะวา พอเรารเทรน Date ออกไปได เชน
Date d = harry.getHireDay();d.setTime(…);
พอเปลยนคาในตวแปร d คา hireDay ทเปน ของ harry กจะเปลยนไปจรงๆ เลยกลายเปน วา ไมไดเปลยนโดยใช setHireDay() หรอ
เมธอดทควรจะเตรยมไวในคลาส Employee
• ดงนน เพอปองกนไมให คาภายในออบเจกต ตนฉบบ เปลยนแปลง
– ตวออบเจกต ทรเทรนออกมาจากเมธอด ควรเปนตวกอปป
– ใชการโคลน
public Date getHireDay() { return (Date) hireDay.clone(); }
รเทรน pointer ทชไปทตวกอปป
Access privileges
• เมธอดสามารถเขาถง private data ของออบเจกตทรนเมธอดนน
• นอกจากน เมธอด สามารถเขาถง private data ของออบ เจกตทกออบเจกตทเปนชนดเดยวกน ตวอยางเชน
เมธอดทเปรยบเทยบลกจางสองคนclass Employee{boolean equals(Employee other){
return name.equals(other.name);}…
เปนออบเจกตอนอน แตเพราะเปนชนดเดยวกน java เลยให
อานคาไดโดยตรง
Private methods
• สวนใหญ เมธอด เราจะใหเปน public• แต private method กมไดเหมอนกน เพอ– เปนเมธอดใชภายในคลาสเทานน อาจเปนสวนทแยก
ยอยออกมาของเมธอดอน และตงใจใหใชโดยคลาสทนยามเทานน
อยาลมวา ถาเปน public คลาสอนจะเรยกใชไดเสมอ
Final instance fields
• คอ ตวแปร ท เราตองการใหเปนคาคงทหลงจากการรนคอนสตรคเตอรแลว
• มกใชกบตวแปรทเปน primitive type หรอ เปนimmutable class ( หมายความวา คลาสนนไมมเมธอดท
เปลยนสงทอยขางในออบเจกตเลย ตวอยาง immutable class กเชน String นนเอง)
• ระวงprivate final Date hireDate; หมายถง ตว pointer ทชอ
hireDate จะไมเปลยนทช แตตวออบเจกตจรงๆยงถกเปลยนขางในได
Static fields and methods• ถาใหตวแปร a เปน static
– จะมตวแปรนตวเดยวตอหนงคลาสเทานน ( นนคอ ม แมวาจะยงไมมออบเจกตเกดขนเลย)– ถงแมจะมออบเจกตของคลาสนเกดขนมาหลายๆอน ตวแปร a กยงมตวเดยวอยด (ทกอ
อบเจกตของคลาสนจะถอวา แชรคา a เดยวกน) แตละออบเจกตไมมของมนเอง ตวอยางเชน
class Employee{private int id;private static int nextId =1;public void setID(){id = nextId;nextId++;}
…ตอหนาถดไป
สมมตเรามออบเจกต Employee ซงเกบในตวแปรharry อยกอนแลว
harry.setId(); จะหมายความเหมอนกบharry.id = Employee.nextId;Employee.nextId++;
object class
Static constants• มเยอะ เชนในคลาส Math มpublic static final double PI = 3.141592653589….
ซงเราสามารถอานคาได โดยไมตองสรางออบเจกตใดๆขนมากอนเลย ดงเชน double x = Math.PI;
• ซงถาไมใช static แลวละก จะถอวา PI เปน instance field ของคลาสMath– ซงจะอานคา PI ไดคราวน ตองสรางออบเจกตกอน– แตละออบเจกตทสราง กจะม PI ของตนเอง (แมวาจะเปนคาคงทตลอดกตาม)
• อกตวอยางของ static constant ทเราไดใชบอย คอ System.out ซงจรงๆแลวโคดนยามของมน
เปนดงนpublic class System{
public static final PrintStream out = …;…
} เปน public แตกเปน final ดวย ทำาใหภายนอก
มาเปลยนคาไมได จงปลอดภย
• จรงๆ คลาส System มเมธอด setOut ซงเปลยน คาของ out ได แตวา มนเปน native method ซง
เขยนดวยภาษาอน เลยไมโดนจาวาจำากดการทำางาน
Static methods
• คอเมธอดทไมทำาการอานหรอเขยนลงบนออบ เจกต เชน
Math.pow(x, a);
• จากภายใน static method เราจะอาน instance field ไมได
• จรงๆ เราเรยก static method จากออบเจกตกได แตจรงๆไมควรทำา คนเขยนจาวามนทำาไวใหเขยน
สะดวก แคนน แตจรงๆความหมายมนผด
• ใชงานในกรณใดบาง– เมธอดไมไดตองการอานหรอเขยนคาตวแปรภายในออบเจกต• กรณนอาจเกดจากขอมลทงหมด ไดจาก พารามเตอรของเมธอด
– เมอเมธอดอาน หรอเขยน แค static field – Main method ใชเปนตวทดสอบคลาสนนๆได
Method parameters
• Java ใช call by value– นนคอ คาพารามเตอรของเมธอด จะเปนคากอปป ไมใชคาของตวแปรทให
add(a,b) -> ไดคาของ a กบ b ไปใชงานภายในเมธอด ตว a กบ b จรงๆ จะไมเปลยนแปลง
public static void tripleValue(double x){x = 3x;
} ถาเราเรยกใชโคดดงน
…
double percent =10;tripleValue(percent);
percent จะยงคงมคา 10 อยหลงเรยกเมธอด เพราะ ไอทเมธอดมนเอาไปคำานวณนะเปนตวกอปป
x ขางในโคด จะอยแคในโคดนนเทานน
• แตพารามเตอรของเมธอด มไดสองแบบคอ เปนprimitive กบเปน object reference
• ซงคราวน เกดการเปลยนได เชนpublic static void tripleValue(Employee m){
m.raiseSalary(200);} เมอเรยกใชEmployee harry = new Employee(…);tripleValue(harry);
จะเกดการ copy pointer ไปใชงาน ดงนนจะเกด pointer ทชไปท ออบเจกตเดยวกน ดงรป
การเปลยน salary จาก m กจะเปนการเปลยนจาก harry ไปดวย
รป
harryEmployee
m
raiseSalary จะไปเปลยนขางในออบเจกตตวจรง
• ระวง เขยนอยางนไมเวรคpublic static void swap(Employee x, Employee y) { Employee temp = x; x = y; y = temp; } แลวไปเรยกใชแบบนEmployee a = new Employee(“Alice”, …);Employee b = new Employee(“Bob”, …);swap(a,b);
ตวทสลบ คอ pointer ทเปนตวกอปป ของ ทง a และ b ดงนน a กบ b จงชไปทเดม
ตลอด
ดรป
a Alice
bBob
x
y
a Alice
bBob
x
y
temp
เมอเมธอดรนแลว
a กบ b ไมเปลยนอะไรเลย และพอเมธอดรนเสรจ x กบ y กจะถกทำาลาย กลายเปน ไมมอะไรเปลยนแปลงเลย
สรป เมธอดทำาอะไรไดหรอไมไดบาง• เปลยนคาตวแปร ของพารามเตอรทเปน
primitive type ไมได• เปลยนคาภายใน ของออบเจกต ได• ใหpointer ชไปทออบเจกตอน ไมได• ดตวอยางจากไฟล ParamTest.java
Object construction
new GregorianCalendar()
new GregorianCalendar(1999, 11, 31)
Overloading: เมธอดมชอเหมอนกนแตมพารามเตอรไมเหมอนกน จาวารวาจะเรยกเมธอดไหน จากการพยายามจบคระหวางไทปของ
พารามเตอร จากนยาม กบ ไทปของพารามเตอรตอนเรยกเมธอด ใชจรง
ถาจบคไมได หรอจบไดมากกวาหนง กจะ compile error
Overloading ใชไดกบเมธอดทกอยาง คอนสตรคเตอรเปนแคหนงในนน
• ชอเมธอด + พารามเตอร เราเรยกรวมๆวา signature• Return type ไมรวมไปดวย ดงนน– ดงนนเมธอดทตางกนแครเทรนไทป จาวาจะนกวาเปนนยามซำาซอน
• ถาในคอนสตรคเตอร เราไมไดเซตคาฟลด คาจะถก เซตใหเปนคา default ของมน เชน
– ตวเลขจะเปน 0– boolean เปน false– Object reference เปน null– อยาลมวา field ไมใช local variable – และตองระวง ถาเราทงใหตวแปรมคา null พอเรยกใช
ทหลง จะทำาให error ได ตวอยางอยหนาถดไป
• สมมตวา ตวแปร hireDay ของ Employee ถกทง ใหเปน null ไว
• ตอนเราเรยกCalendar.setTime(harry.getHireDay());– จะมการ throw exception ได เพราะวา setTime ดนได
รบ null เปนพารามเตอร ซงในโคดไมสามารถนำาไปใชงานได
Default constructor
• คอ คอนสตรคเตอร ทไมมพารามเตอร• ถาในโปรแกรม เราไมไดเขยนคอนสตรคเตอรซก
ตว จาวาจะสรางตว default ใหเราเอง– ซงจะเซตคาของ instance field ทงหมดใหเปนคา
default• ถาคลาสมการนยามคอนสตรคเตอร แตวาไมม
การนยาม default constructor มา จาวาจะไมสราง ตว default constructor ให ดงนนกจะเรยกใชตว
default constructor ไมไดดวย
• ทนยามของตวแปรแตละตว เราสามารถ assign คาใหมนไดเลย โดยคาเหลานจะอยกอนทคอนสตรคเตอรจะถกเรยก ตวอยาง
เชน:class Employee{…static int assignID(){
int r = nextId;nextId++;return r;
…private int id = assignId();
}
ตรงนไมไดอยในคอน สตรคเตอร แตเปนตรง
นยามตวแปรเลย ซงจะถกรนกอนทคอนสตรคเตอร
จะทำางาน รนเมธอดกได
ตวนจะเปนตวท initialize คาท เราอาจไมตองการมา
initialize ในคอนสตรคเตอรทกตว
การตงชอพารามเตอรpublic Employee(String n, double s){
name = n;salary = s;
} อานแคตรงน จะไมรวา สองตวนจะมาจากไหน
ดงนนจงตองเสยเวลาอานโคด
public Employee(String aName, double aSalary){name = aName;salary = aSalary;
}
เขาใจงาย ชดเจน
public Employee(String name, double salary){this.name = name;this.salary = salary;
} ชอเดยวกบinstance field ไดแตตอนเขยนโคดในเมธอดตองแยกให
เรยบรอย
การเรยกใชคอนสตรคเตอรอนของคลาสเดยวกน
public Employee(double s){this(“Employee #” + nextId, s);nextId++;
} เรยกใชคอนสตรคเตอรตวอนของ คลาสเดยวกนได
ดงนนถาเราเขยนคอนสตรคเตอร ตวพนใหละเอยด กสามารถถกตว
อนเรยกใชไดหมด จะไดประหยดเวลาในการเขยนคอนสตรคเตอรตว
หลงๆ
Initialization block private int id; private String name = ""; // instance field initialization private double salary;
// static initialization block static { Random generator = new Random(); // set nextId to a random number between 0 and 9999 nextId = generator.nextInt(10000); }
// object initialization block { id = nextId; nextId++; }
อนนเราอยใน คลาส
Employee นะ
Execute เมอออบเจกตของคลาส นถกสราง ซงตวโคดนจะถกรน
กอนคอนสตรคเตอร
ใช initialize static variable แตตาม
ปกตใชกบการinitialize ทคอนขางซบซอนเทานน
static ก initialize ไดตรงนเหมอนกน
• ลำาดบการรนจะเปนดงน– ตอนแรกคาทกคาเปน default– Field initializer และ initialization block จะถกรน ตาม
ลำาดบบรรทดในโคดวาอนไหนจะมากอนมาหลง (static initialization กทำาตามลำาดบนเหมอนกน)
– ถาบรรทดแรกของคอนสตรคเตอร เปนการเรยกคอนสตรค เตอรอกตว คอนสตรคเตอรตวทถกเรยกจะโดนรนกอน
– คอนสตรคเตอร• มาดตวอยางโปรแกรมทใชคอนสตรคเตอรกน
ConstructorTest.java
packages
• กลมของคลาสทใชดวยกน เรยกวา package• ในจาวาเองกม– java.lang– java.util– java.net
• เราจดแพคเกจเองได จดเหมอนกบการจดโฟลเดอรทเกบไฟล
• ทมมาใหเราแลว จะอยใน java หรอ javax
• ทำาไมตองม package– เหตผลสำาคญคอ จะไดไมมปญหาการทคลาสชอซำากน– สมมตมคนคดคลาส Employee มาสองคน ถาตางคน
ตางเอาเขา package คนละอน จาวากจะรวาเปนคนละ คลาสกน ไมสบสนวามชอซำา
– แตทงน ชอ package กตองตงใหตางกนดวย• เพอทจะทำาใหไดชอเฉพาะมากๆ sun ใหใชชอเวบไซตกลบหลง
เชน com.vishnu• จากนนกสามารถทำา subpackage ตอได เชน
com.vishnu.progmeth
• สำาหรบจาวาเอง java.util กบ java.util.jar ถอวา เปนสองแพกเกจทไมมอะไรเกยวของกนเลย
การ import• คลาสหนงๆ สามารถใชงานคลาสทอยในแพกเกจเดยวกน และ
คลาสในแพกเกจอนทเปน public• แตวา คลาสในแพกเกจอน จะมองไมเหน ตองมการบอก โดยมสองวธ– ใสชอแพกเกจขางหนาชอคลาสทกคลาสทเอามาจากแพกเกจอน เชนJava.util.Date today = new java.util.Date();
• แตวธนมนทำาใหเขยนยดยาว– วธทสองคอการ import
• เขยน import ดานบนของไฟล ตอจากนยามpackage ทเรานยาม package ของคลาส
• import java.util.*; จะเปนการอมพอรตทกไฟลจากแพกเกจนน
• แตวา ใชงานแบบนไมไดimport java.*;import java.*.*;
• และทตองระวงอกอยางคอ ถาสองแพกเกจดนม คลาสชอเหมอนกน เชน java.util.* กบ java.sql.*
มคลาส Date ทงค– ถาเราอมพอรตทงค เราจะใช Date ไมได– แกโดย import java.util.Date; เขยนอนนลงไปเพม– หรอ ถาเกดตองใช Date จากทงสองคลาสจรงๆ กตองเขยนชอคลาสทรวมชอแพกเกจดวยตลอด
Static import
import static java.lang.System.*;
จะทำาใหเรยกใช static เมธอด และ static field จากคลาสSystem ได โดยไมตองเอยชอคลาสกอน เชน
out.println(“…”);
ใชไดดกบคลาส Math และการใชงาน constant เพราะใชไดอยางเปนธรรมชาตมากขน
การนยามวาคลาสเรา อยในแพกเกจอะไร
• ใสชอแพกเกจ ดานบนสดของ source file ตวอยางเชน
package com.vishnu.progmeth;public class Employee{……}
ถาเราไมใสชอแพกเกจใหคลาสเรา จาวาจะถอวา คลาสนนอยใน default package
การเกบไฟลในโฟลเดอร• เมอเรานยามแพกเกจไปแลว การเกบไฟลใน
โฟลเดอรของคอมพวเตอรเรา กตองทำาตามชอ ของแพกเกจ เชน
• ไฟลทงหมดทอยในแพกเกจcom.vishnu.progmeth จะตองถกเกบในโฟลเดอรcom\vishnu\progmeth ซงตองอยใน base directory อกทหนง
• ตองเกบใหถก เพราะวา .class ไฟลจะถกเกบไวตาม นเหมอนกน ถาเกด source file ไมไดอยตาม
โฟลเดอรน จะคอมไพลไดแตรนไมได เพราะการ หา .class ไฟล จะหาจากโฟลเดอรทเรานยามแพก
เกจ
Package scope
• ถาเราไมไดบอกวา คลาส ตวแปร หรอเมธอด เปน public หรอ private จาวาจะถอวา เมธอดอนๆ ท
อยในแพกเกจเดยวกน จะสามารถมองเหน คลาส ตวแปร หรอเมธอดนนได
• เราสามารถ seal package ได– เปนการปองกน ไมใหคนอนมาเตมไฟลลงใน แพกเกจของเรา
– ทำาโดยการ seal jar ( จะเหนวา eclipse จะมคำาสงพวกนในตว)
Class path
• Jar file คอ zip ไฟล ทเกบคลาสไฟลตางๆ และเกบ subdirectory ไว
• เราตองตงคา classpathc:\classdir;.;c:\archives\archive.jar
Base directory Jar file
Current directory
ใช * ได
• เวลาจาวาจะหาคลาส มนจะดทตว library ของมนกอน• แลวคอยมาด class path• สมมตเรามคลาสคลาสหนงทอมพอรตดงนimport java.util.*;import com.vishnu.progmeth.*;
ถาในไฟลนมการใชงาน คลาส Employee จาวาจะพยายามไปด
Java.lang.Employee, java.util.Employee, com.vishnu.progmeth.Employee และ Employee ในcurrent package โดยจะหาแตละไฟลพวกน จากทกๆ
โฟลเดอรทนยามใน class path