object and classeschate/2110210/objectandclasses.pdf · –...
TRANSCRIPT
Object and classes
บทนเรยนอะไรบางบทนเรยนอะไรบาง
b d• แนะนา Object‐oriented programming
• บอกวธการสราง object จากคลาสทจาวาใหมาj• สอนวธสรางคลาสของเราเอง
แนะนา Object‐Oriented Programmingแนะนา Object‐Oriented Programming
โป ป • โปรแกรมประกอบขนจากออบเจกต
• แตละออบเจกตจะมฟงกชนใหเรยกใช
– คนเรยกใชไมจาเปนตองรวาขางในออบเจกตทางานยงไง
ใ ใ ไ – ขอใหใชไดตามทตองการกพอ
• วธคดในการโปรแกรม
– เมอตองการแกปญหา ใหออกแบบตวขอมลทตองใชกอน
– แลววธแกปญหาคอยตามมาแลววธแกปญหาคอยตามมา
คลาสคลาส
l • คลาสคอ template ทเราจะใชสรางออบเจกต– พดงายๆ มนเปนตวกาหนดวา ออบเจกตทสรางจากมน จะมขอมลอะไรอย ๆ
ภายในบาง
– คลาสเปรยบเสมอนแมพมพ สวนออบเจกตกเปนสงทแมพมพพมพออกมาคลาสเปรยบเสมอนแมพมพ สวนออบเจกตกเปนสงทแมพมพพมพออกมา
• เมอเราสรางออบเจกตขนจากคลาส
– เราเรยกเหตการณนวา การสราง instance ของคลาส
ใ • ภายในแตละออบเจกต
– ขอมล หรอดาตา เราเรยกวา instance fields หรอ instance variables
• แตละออบเจกต จะมคาของแตละ instance field เปนของตนเอง ไมใชคารวมกบออบเจกตอนรวมกบออบเจกตอน
• สถานะของคาตวแปรเหลานทงหมด ถอเปน state ของออบเจกต• ซงเมอเรยกเมธอด state ของออบเจกตอาจเปลยนได• ซงเมอเรยกเมธอด state ของออบเจกตอาจเปลยนได
สวนฟงกชนทออบเจกตนนเรยกเพอจดการขอมลขางตน เรยกวา – สวนฟงกชนทออบเจกตนนเรยกเพอจดการขอมลขางตน เรยกวา methods
i t fi ld โ• หามเขาถงคาของ instance field โดยตรง • ตองอาน และเขยนคาตวแปร จากเมธอดเทานน
• ทงนเพอ
– ปองกนการยดคาผดๆ ใสลงไปใน instance fieldปองกนการยดคาผดๆ ใสลงไปใน instance field• เชน a.x = 100; จรงๆ x อาจจะมคาเกน 99 ไมได ดงนนเขยนเมธอดคมดกวา
– เวลาจะเปลยนพฤตกรรมการทาอะไร จะไดแกในเมธอด ทเดยว ไมตองมาแกหลายๆทๆ
•
extendsextends
d• ถาเราสรางคลาสใหม โดยใชการ extends จากคลาสเกา– คลาสใหมจะไดรบ ตวแปร และเมธอด มาจากคลาสเกาทงหมด
– เราแคเขยนตวแปรกบเมธอดเพม ทคลาสใหมจะมเทานน กพอ
• การ extends นน ใชหลกของการ inheritance ซงจะสอนใน• การ extends นน ใชหลกของการ inheritance ซงจะสอนในบทตอไป
Relationship between classesRelationship between classes
• ส ส ไ ไ • แตละคลาส สมพนธกนยงไงไดบาง
• Dependence (uses‐a)A d d B A ใ B– คลาส Aจะ depend on คลาส B ถาคลาส A มการใชออบเจกตของคลาส B
• Aggregation (has‐a) ใ A ใ B ไ ป– ออบเจกตในคลาส A สามารถเกบ ออบเจกตในคลาส B ได นเรยกวาเปน
aggregation• Inheritance (is a)• Inheritance (is‐a)
– Car extends จาก Vehicle– Car จะถอวา เฉพาะเจาะจง หรอ specialise กวา สามารถทาสงท VehicleCar จะถอวา เฉพาะเจาะจง หรอ specialise กวา สามารถทาสงท Vehicle
ทาได และกทาอยางอนไดเพมเตมดวย
– Car is a Vehicle แตวา Vehicle ไมจาเปนตองเปน Car
การวาดความสมพนธการวาดความสมพนธ
• เดยวนใช UML Diagram– ปกต คลาสจะวาดดวยสเหลยม
– ความสมพนธจะวาดเปนเสนตางๆกนไป
ไปลองใช ArgoUML (http://argouml tigris org) หรอ – ไปลองใช ArgoUML (http://argouml.tigris.org) หรอ
Violet (http://violet.sourceforge.net)
การใชงานคลาสทจาวาสรางไวแลวการใชงานคลาสทจาวาสรางไวแลว
ใ ไ • จะใชงานออบเจกตไดนน ตอง
– สรางออบเจกต
– กาหนดคาตางๆสาหรบขอมลภายในออบเจกต
– ใชงานโดยการเรยกเมธอดทใชกบออบเจกตนนได (แนนอนวาตองนยามเมธ– ใชงานโดยการเรยกเมธอดทใชกบออบเจกตนนได (แนนอนวาตองนยามเมธ
อดกอน)
มา zoom ดทการสรางออบเจกตมา zoom ดทการสรางออบเจกต
()Date x = new Date();
จงกอเกดตวตน คอนสตรคเตอร เปนตวบอกชนดของ
ออบเจกต และเรยกโคดมารนเพอ
i iti li initialize ตวออบเจกตนนดวย
พอสรางเสรจกใชงานไดพอสรางเสรจกใชงานได
ไ () • เชนเอาไปปรน (แตตองนยาม toString() กอน เพราะจาวา ปรนออบเจกตไมเปน เราตองบอกมนวาจะปรนยงไง)
– System.out.println(new Date()); หรอ
String s = new Date() toString();– String s = new Date().toString();
ตรงนเปนการเอาออบเจกตทสรางขนมา ไปเรยกเมธอด
toString() ในทนท แตจรงๆเราเรยกจากตวแปรกได
ซงควรใชตวแปร ถาจะเกบออบเจกตไวใชตอ
สภาพ ณ เวลาตางๆ สภาพ ณ เวลาตางๆ
• Date x
x มตวแปร x ซงสามารถชไปทออบเจกตทเปนไทป xDate ได
แตยงไมมตวออบเจกตทจะใหชเลย
• เมอยงไมมตวตนออบเจกต จงเรยกเมธอดไมไดเมอยงไมมตวตนออบเจกต จงเรยกเมธอดไมได
– ฉะนนคาสง s = x.toString(); จง error
ไ • ดงนนตองสรางออบเจกตใหมตวตน เพอเอา x ชไปทออบเจกตนน• มทางเลอกสองทาง
– ใชคอนสตรคเตอร: x = new Date();
ป ใ ไป ป – ทาตวแปรใหชไปทตวแปรอนทเคยสรางออบเจกตสมบรณมากอนแลว: x = birthday;
• Date x = new Date();
xx
Dateตวแปร เปน pointer โยงไปยงกอนออบเจกต
ทแทจรงทแทจรง
• ถาเราทาตอจากขางบนน โดยเขยนวา Date x2 = x; xx
DateX2 จะเหนวา ตวแปรสองตวจะชไปทกอน
ออบเจกตเดยวกน ดงนนถาเปลยน Date object ตวน จาก x กจะเหนความobject ตวน จาก x กจะเหนความเปลยนแปลงถาดจาก x2 ดวยเหมอนกน
ป ไ ใ ไปไ ไ • เราสามารถบอกตวแปรวา ไมใหชไปไหน กได
– X = null; ;
• สามารถใช null ในการตรวจสภาพออบเจกตไดif ( ! ll){ }– if (x != null){ }
• แตอยาลมวา ถาตวแปรไหนเปน null แลว จะเรยกเมธอดใชไมได
error หมด
ตวอยางคลาสตวอยางคลาส
• Date– ออบเจกตไทปน เปนขอมลจดหนงของเวลา
– มเมธอดใหเราเปรยบเทยบกบ Date อน วา Date ไหนมากอนมาหลง เชนif(today before(birthday))if(today.before(birthday))
System.out.println(“Have some time left.”);
G i C l d• GregorianCalendar– Extends มาจาก Calendar ทนยามปฏทนอยางทวไป
มเมธอดเยอะ มคอนสตรคเตอรหลายตว เชน– มเมธอดเยอะ มคอนสตรคเตอรหลายตว เชน
new GregorianCalendar() ซงสรางออบเจกตทเกบวนเวลา ณ ตอนสราง
new GregorianCalendar(1999, 11, 31) ซงสรางออบเจกตทเกบขอมล เวลาเทยงคน วนท 31 ธค 1999 (เดอน เรมนบเดอนแรกทเลข 0) ไ ไหรอวาจะใชคอนสตรคเตอรทละเอยดกวา ทกาหนดเวลาไดดวย กได
ไ ป ใ ป ไ ใ ไ สงเกต วาเราไมจาเปนตองรวาขางในเกบวนเวลา เดอนป ยงไง แคเรยกใชเมธอดไดกพอ
Mutator and accessor methodsMutator and accessor methods
ไ ไ• จะจดการกบคาตางๆทเกบไว จากตวอยาง Date ไดตอง• อานได และเขยนได
• สาหรบการอานคา ใช accessor methods (หมายถง เมธอดทใ ใ ) ใชอานคาตางๆในออบเจกต) ตวอยางเชน
// construct d as current date
GregorianCalendar d = new GregorianCalendar();
d d ( l d )int today = d.get(Calendar.DAY_OF_MONTH);int month = d.get(Calendar.MONTH);
• ป ใ ใ mutator methods (• การเปลยนคาตางๆภายในออบเจกต ใช mutator methods (เมธอดทใชสาหรบเปลยนคา) ตวอยางเชน
d set(CalendarDAY OF MONTH 15)d.set(Calendar.DAY_OF_MONTH, 15);d.set(Calendar.YEAR, 2001);d (C l d MONTH C l d APRIL)d.set(Calendar.MONTH, Calendar.APRIL);
ไ ทงนขนกบวาคลาสนนมเมธอดอะไรใหเปลยนคาของขอมลบาง อยางคลาสปฏทน น มเมธอดทชวยเลอนวนเวลา ดวย คอ
d dd(C l d MONTH 3) ป dd.add(Calendar.MONTH, 3); เปนการเลอนวนเวลา ของ d ออกไปสามเดอน
• โดยปกตแลว accessor จะมคานาหนาวา get สวน mutatorจะมคานาหนาวา set ตวอยางเชน
Date time = calendar.getTime(); เอาคาวนเวลา (ทเปนชนด
Date) ออกจากปฏทน มา
เกบไวในตวแปร time สมมตวาออบเจกตนมอยแลว
เปนชนด Calendar นะ
calendar.setTime(time); เปนชนด Calendar นะ
เซตเวลา ของ calendarเซตเวลา ของ calendar object
ตวอยางเพมเตมตวอยางเพมเตม
• ป Date ป • รวนเดอนป และตองการสราง Date ทแทนวนเดอนปนน– ตอนน Date ไมมเมธอดททาได จงตองใช calendar ชวยGregorianCalendar cal new GregorianCalendar(yearGregorianCalendar cal = new GregorianCalendar(year, month, day);
Date hireDay = calendar.getTime();Date hireDay calendar.getTime();
• ม Date object อย ตองการหาคาตางๆจาก Date object นนj ๆ jGregorianCalendar cal = new GregorianCalendar();Cal setTime(hireDay);Cal.setTime(hireDay);int year = cal.get(Calendar.YEAR);
ตวอยางโปรแกรม วาดปฏทนของเดอนนตวอยางโปรแกรม วาดปฏทนของเดอนน
l d• calendar
การนยามคลาสไวใชเองการนยามคลาสไวใชเอง
ไ ไ • คลาสทเราจะนยามจากนไป ไมจาเปนตองม main
• แตจะม field กบเมธอด
• การเขยนโปรแกรม จะเกดจากการใช main method ของคลาส ใ หนง เรยกใชเมธอดของคลาสอนๆ
• เดยวลองมาดคลาสสาหรบเกบขอมลลกจาง เอาไวใชกบการจาย
เงนเดอนดเงนเดอนด
class Employee{//constructor//constructorpublic Employee(String n, double s, int year, int month, int day){
name = n;salary ssalary = s;GregorianCalendar calendar = new GregorianCalendar(year, month‐1,
day);hireDay calendar getTime();hireDay = calendar.getTime();
}
// h d//methodpublic String getName(){
return name;} …//instance fields//private String name;private double salary;private Date hireDay;private Date hireDay;
ตวอยางโปรแกรมทใชงาน Employeeตวอยางโปรแกรมทใชงาน Employee
E l T t• EmployeeTest
• ใชงานจรงๆแคสรางอาเรยแลวเตมรายละเอยดลกจางสามคนลงไปใชงานจรงๆแคสรางอาเรยแลวเตมรายละเอยดลกจางสามคนลงไป
• จากนนลปเพมเงนเดอนทกคน คนละ 5%• แลวพมพรายละเอยดของทกคนออกมา
– อนนเรยกเมธอดหลายอน เพอใหไดขอมลทกสวน
• สงเกต i ใ E l T t – วา main จะอยใน EmployeeTest เทานน
– ชอไฟลจะตองตรงกบชอคลาสทเปน public – ในหนงไฟลม public class ไดแคอนเดยว แตนอกนนจะมกคลาสกไดp– ตอนคอมไพล มนจะแยกไฟล .class ให– เวลารน ตองรนคลาสทม main เสมอ
• ไฟ ไ ใ • ถาเราแยกไฟลแตแรก ตอนคอมไพล สามารถใช
javac Employee*.java เพอคอมไพลทกไฟลได หรอ เรยก
Javac EmployeeTest.java จาวาจะคอมไพล EmployeeTest เมอมนเหนวา มการใช
Employee ภายใน มนจะไปหา Employee.class ซงถาหาไมเจอ ไ Employee java ใ มนจะคอมไพลจาก Employee.java ใหเอง
ไฟ l j นอกจากน ถงหาเจอ แตไฟล .class นนเกากวา .java ทม มนกจะคอมไพลใหมใหเหมอนกน
มาด Employee กนอยางละเอยดหนอยมาด Employee กนอยางละเอยดหนอย
ไ • สงเกตไดวา
– ทกเมธอดเปน public นนคอ เมธอดทกเมธอดในทกคลาสสามารถเรยกเมธไ อดเหลานได
– ทกตวแปรเปน private นนคอ เมธอดทอานคาจากตวแปรเหลานไดl โดยตรงจะตองเปนเมธอดจากคลาส Employee เทานน
• ไมควรใหตวแปรเปน public เพราะสวนไหนของโปรแกรมจะมาเปลยนขอมลกได เปลยนอยางไรกได อาจจะมการกระทาตองหามทเราไมทนคด เกดขนไดเปลยนอยางไรกได อาจจะมการกระทาตองหามทเราไมทนคด เกดขนได
– ตวแปร สองตว กเปนออบเจกต name เปน String สวน hireDayเปน Dateเปน Date
• ใชแลว ออบเจกตสามารถใสออบเจกตอนๆ ซอนๆกนได
constructorsคอนสตรคเตอรไมรเทรนคา constructors
bli E l (St i d bl i t i tpublic Employee(String n, double s, int year, intmonth, int day){ ชอตองเหมอนชอคลาส คอนสตรคเตอรใชเซตคา{name = n;l
ชอตองเหมอนชอคลาส คอนสตรคเตอรใชเซตคา
ภายในออบเจกตทพงถกสราง ใหเปนไปตามทเรา
ตองการsalary = s;GregorianCalendar calendar = new G i C l d ( th 1 d )GregorianCalendar(year, month ‐ 1, day);// GregorianCalendar uses 0 for Januaryh l d ()hireDay = calendar.getTime();
}
new Employee(“James Bond, 100000, 1950, 1, 1); จะได object ของคลาส Employee ทมขางในเปน
name = “James Bond”Salary = 100000;Salary = 100000;
hireDay = January 1, 1950
คอนสตรคเตอร เรยกใชไดพรอม new เทานน ดงนนจะไมสามารถใชกบ
ออบเจกตทถกสรางขนแลวไดออบเจกตทถกสรางขนแลวได
ขอควรระวงขอควรระวง
l l bl f ld ไ• อยาให local variable มชอเดยวกบ field ทเรานยามไว
public Employee(String n, double s, int year, intpublic Employee(String n, double s, int year, intmonth, int day)
{{
String name = n;g ;
double salary = s;
จะกลายเปนใหคากบ local variable ไป ไมไดใหคาอะไรกบ fields
Implicit and explicit parametersImplicit and explicit parameters
จากจาก
public void raiseSalary(double byPercent){{double raise = salary * byPercent / 100;salary += raise;salary += raise;
}
ถาเราเรยก
Employee number007 = new Employee(“James BondEmployee number007 new Employee( James Bond, 100000, 1950, 1, 1);
number007.raiseSalary(5);
Implicit parameter Explicit parameter
โ ไป ไ • ซงโคดทรนไป จะเหมอนกบไดทา
double raise = number007.salary * byPercent / 100;y y / ;
number007.salary += raise;
ซงถาเราอยากใหมการอางถง implicit parameter เราจะทาไดโดยใช
คาวา this ตวอยางเชน ในโคดของคอนสตรคเตอรเราอาจจะใช
double raise = this salary * byPercent / 100;double raise = this.salary byPercent / 100;
this.salary += raise;
คราวนมาลองดเมธอดในคลาส Employee กนหนอยคราวนมาลองดเมธอดในคลาส Employee กนหนอย
public String getName() พวกนเปน accessorpublic String getName(){return name;
}
พวกนเปน accessor
•name ตองไมเปน public เพราะทางผเขยนไม}
public double getSalary()
name ตองไมเปน public เพราะทางผเขยนไมตองการให name ถกเปลยนหลงจากใหชอผานคอนสตรคเตอรไปแลว ดงนน พอเปน private จงปองกนการ
{return salary;
}
ถกเปลยนชอได
•salary เปลยนไดกจรง แตถาเปน private แบบนจะ}
public Date getHireDay(){
•salary เปลยนไดกจรง แตถาเปน private แบบนจะเปลยนไดดวย raiseSalary เทานน ซงถาเกดอะไร
ผดพลาด เรากจะไดไปแกท raiseSalary ทเดยว ถา{return hireDay;
}
yเปน public แลวละก กวาจะตามหาทผดเจอ จะยากมาก
การใชเมธอดในการเปลยนขอมลเทานน มประโยชนจรงๆการใชเมธอดในการเปลยนขอมลเทานน มประโยชนจรงๆ
Employee ป ป ช ป จากตวอยาง Employee ถามการเปลยนรปแบบของชอเปน
String firstName;String lastName;String lastName;
เวลาเราตองการดงชอของ Employee ออกมา เรากทาแคไปแก getname เทานน อาจp y gแกใหเปน return firstName + “ “ + lastName;
ไ ส โปซงจะไมตองมผลกระทบกบสวนอนของโปรแกรม
นอกจากน เมธอดยงตรวจ error ไปในตวได เชนใหโคดของเมธอดเชคกอนเสมอวา salaryนอกจากน เมธอดยงตรวจ error ไปในตวได เชนใหโคดของเมธอดเชคกอนเสมอวา salary ตองไมตากวา 0 ดงนน เมอบงคบวาตองเรยกเมธอดเพอเปลยน salary กจะทาใหคา salary ไมมวนตากวา 0 อยางแนนอน
ระวงระวง
bli i ()public Date getHireDay(){{return hireDay;
}}
จรงๆ โคดนไมเวรค เพราะวา พอเรารเทรน Date ออกไปได เชน
Date d = harry getHireDay();Date d harry.getHireDay();d.setTime(…); พอเปลยนคาในตวแปร d คา hireDay ทเปนของ harry กจะ
เปลยนไปจรงๆ เลยกลายเปนวา ไมไดเปลยนโดยใช
setHireDay() หรอเมธอดทควรจะเตรยมไวในคลาส
Employee
ป ไ ใ ใ ป ป• ดงนน เพอปองกนไมให คาภายในออบเจกตตนฉบบ เปลยนแปลง
– ตวออบเจกต ทรเทรนออกมาจากเมธอด ควรเปนตวกอปป
– ใชการโคลนรเทรน pointer ทชไปทตว
public Date getHireDay()กอปป
{
return (Date) hireDay clone();return (Date) hireDay.clone();
}
Access privilegesAccess privileges
i t d t • เมธอดสามารถเขาถง private data ของออบเจกตทรนเมธอดนน• นอกจากน เมธอด สามารถเขาถง private data ของออบเจกตทก
ออบเจกตทเปนชนดเดยวกน ตวอยางเชน เมธอดทเปรยบเทยบลกจางสองคน
class Employee{boolean equals(Employee other){boolean equals(Employee other){return name.equals(other.name);
}}… เปนออบเจกตอนอน แตเพราะเปนชนด
j ใ ไ โเดยวกน java เลยใหอานคาไดโดยตรง
Private methodsPrivate methods
bl• สวนใหญ เมธอด เราจะใหเปน public
• แต private method กมไดเหมอนกน เพอp– เปนเมธอดใชภายในคลาสเทานน อาจเปนสวนทแยกยอยออกมาของเมธอด
อน และตงใจใหใชโดยคลาสทนยามเทานนอน และตงใจใหใชโดยคลาสทนยามเทานน
อยาลมวา ถาเปน public คลาสอนจะเรยกใชไดเสมอ
Final instance fieldsFinal instance fields
ป ใ ป • คอ ตวแปร ท เราตองการใหเปนคาคงทหลงจากการรนคอนสตรคเตอรแลว
• มกใชกบตวแปรทเปน primitive type หรอ เปน immutable p ypclass (หมายความวา คลาสนนไมมเมธอดทเปลยนสงทอยขางใน
ออบเจกตเลย ตวอยาง immutable class กเชน String นนเอง)g )• ระวง
i fi l D hi D i private final Date hireDate; หมายถง ตว pointer ทชอ
hireDate จะไมเปลยนทช แตตวออบเจกตจรงๆยงถกเปลยนขางในได
Static fields and methodsStatic fields and methods
• ใ ป a ป static• ถาใหตวแปร a เปน static – จะมตวแปรนตวเดยวตอหนงคลาสเทานน (นนคอ ม แมวาจะยงไมมออบเจกตเกดขนเลย)
– ถงแมจะมออบเจกตของคลาสนเกดขนมาหลายๆอน ตวแปร a กยงมตวเดยวอยด (ทกออบเจกต
ๆ ของคลาสนจะถอวา แชรคา a เดยวกน) แตละออบเจกตไมมของมนเอง ตวอยางเชน
class Employee{private int id;private int id;private static int nextId =1;public void setID(){id = nextId;nextId++;
}}…ตอหนาถดไป
l hสมมตเรามออบเจกต Employee ซงเกบในตวแปร harry อยกอนแลว
harry.setId(); จะหมายความเหมอนกบh id E l tIdharry.id = Employee.nextId;
Employee.nextId++;
object class
Static constantsStatic constants
• ใ Math • มเยอะ เชนในคลาส 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{
bli i fi l P i Spublic static final PrintStream out = …;
…}
เปน public แตกเปน final ดวย ทาใหภายนอกมาเปลยนคาไมได จงปลอดภย
ไ• จรงๆ คลาส System มเมธอด setOut ซงเปลยนคาของ out ได
แตวา มนเปน native method ซงเขยนดวยภาษาอน เลยไมโดนจาวาจากดการทางาน
Static methodsStatic methods
ไ • คอเมธอดทไมทาการอานหรอเขยนลงบนออบเจกต เชน
Math.pow(x, a);Math.pow(x, a);
• จากภายใน static method เราจะอาน instance field ไมได
• จรงๆ เราเรยก static method จากออบเจกตกได แตจรงๆไมควรทา คนเขยนจาวามนทาไวใหเขยนสะดวก แคนน แตจรงๆความหมายทา คนเขยนจาวามนทาไวใหเขยนสะดวก แคนน แตจรงๆความหมาย
มนผด
• ใชงานในกรณใดบาง
– เมธอดไมไดตองการอานหรอเขยนคาตวแปรภายในออบเจกต
• กรณนอาจเกดจากขอมลทงหมด ไดจาก พารามเตอรของเมธอด• กรณนอาจเกดจากขอมลทงหมด ไดจาก พารามเตอรของเมธอด
– เมอเมธอดอาน หรอเขยน แค static field
– Main method ใชเปนตวทดสอบคลาสนนๆได
Method parametersMethod parameters
J ใ ll b l• 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 ขางในโคด จะอยแคในโคดนนเทานน x ขางในโคด จะอยแคในโคดนนเทานน
• แตพารามเตอรของเมธอด มไดสองแบบคอ เปน primitive กบเปน bj t fobject reference
• ซงคราวน เกดการเปลยนได เชน
public static void tripleValue(Employee m){m.raiseSalary(200);
}เมอเรยกใช
Employee harry = new Employee(…);tripleValue(harry);
จะเกดการ copy pointer ไปใชงาน ดงนนจะเกด pointer ทชไปทออบเจกตเดยวกน ดงรป
การเปลยน salary จาก m กจะเปนการเปลยนจาก harry ไปดวย
รปรป
harryEmployee
mm
raiseSalary จะไปเปลยนขางในออบเจกตตวจรง
• ระวง เขยนอยางนไมเวรค
public static void swap(Employee x, Employee y){{Employee temp = x;x y;x = y;y = temp;
}แลวไปเรยกใชแบบน แลวไปเรยกใชแบบน
Employee a = new Employee(“Alice”, …);Employee b = new Employee(“Bob”, …);swap(a,b); ตวทสลบ คอ pointer ทเปนตวกอปป ของทง a และ b
a b ไป p( )
ดงนน a กบ b จงชไปทเดมตลอด
ดรปดรป
a Alice
bBob
x
y
เมอเมธอดรนแลว
a Alice
bBob
x temp
y
p
a กบ b ไมเปลยนอะไรเลย และพอเมธอดรนเสรจ x กบ y กจะถกทาลายป ไ ไ ป ปกลายเปน ไมมอะไรเปลยนแปลงเลย
สรป เมธอดทาอะไรไดหรอไมไดบางสรป เมธอดทาอะไรไดหรอไมไดบาง
ไ ไ• เปลยนคาตวแปร ของพารามเตอรทเปน primitive type ไมได• เปลยนคาภายใน ของออบเจกต ได
• ใหpointer ชไปทออบเจกตอน ไมได
• ดตวอยางจากไฟล ParamTest.java
Object constructionObject construction
G i C l d ()new GregorianCalendar()
new GregorianCalendar(1999, 11, 31)
Overloading: เมธอดมชอเหมอนกนแตมพารามเตอรไมเหมอนกนOverloading: เมธอดมชอเหมอนกนแตมพารามเตอรไมเหมอนกนจาวารวาจะเรยกเมธอดไหน จากการพยายามจบคระหวางไทปของพารามเตอร จากนยาม กบ
ไทปของพารามเตอรตอนเรยกเมธอดใชจรง
ถาจบคไมได หรอจบไดมากกวาหนง กจะ compile error
Overloading ใชไดกบเมธอดทกอยาง คอนสตรคเตอรเปนแคหนงในนน
• ชอเมธอด + พารามเตอร เราเรยกรวมๆวา signature
• Return type ไมรวมไปดวย ดงนน
– ดงนนเมธอดทตางกนแครเทรนไทป จาวาจะนกวาเปนนยามซาซอนดงนนเมธอดทตางกนแครเทรนไทป จาวาจะนกวาเปนนยามซาซอน
• ถาในคอนสตรคเตอร เราไมไดเซตคาฟลด คาจะถกเซตใหเปนคา
default ของมน เชน
– ตวเลขจะเปน 0
– boolean เปน false
Object reference เปน null– Object reference เปน null
– อยาลมวา field ไมใช local variable
– และตองระวง ถาเราทงใหตวแปรมคา null พอเรยกใชทหลง จะทาให
error ได ตวอยางอยหนาถดไป
• สมมตวา ตวแปร hireDay ของ Employee ถกทงใหเปน null ไว
• ตอนเราเรยก Calendar setTime(harry getHireDay());• ตอนเราเรยก Calendar.setTime(harry.getHireDay());– จะมการ throw exception ได เพราะวา setTime ดนไดรบ null
ป ใ โ ไ ไปใ ไ เปนพารามเตอร ซงในโคดไมสามารถนาไปใชงานได
Default constructorDefault constructor
ไ • คอ คอนสตรคเตอร ทไมมพารามเตอร
• ถาในโปรแกรม เราไมไดเขยนคอนสตรคเตอรซกตว จาวาจะสรางตว
default ใหเราเอง instance field ใ ป 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;name n;
salary = s;} อานแคตรงน จะไมรวาสองตวนจะ
มาจากไหน ดงนนจงตองเสยเวลา
อานโคด
public Employee(String aName, double aSalary){
name = aName;name aName;
salary = aSalary;}
ใ เขาใจงาย ชดเจน
public Employee(String name, double salary){
this.name = name;this.name name;
this.salary = salary;}
ชอเดยวกบ instance field ได แตตอนเขยนโคด
ในเมธอดตองแยกใหในเมธอดตองแยกให
เรยบรอย
การเรยกใชคอนสตรคเตอรอนของคลาสเดยวกนการเรยกใชคอนสตรคเตอรอนของคลาสเดยวกน
public Employee(double s){
this(“Employee #” + nextId, s);this( Employee # + nextId, s);
nextId++;}
เรยกใชคอนสตรคเตอรตวอนของคลาสเดยวกนได เรยกใชคอนสตรคเตอรตวอนของคลาสเดยวกนได
ดงนนถาเราเขยนคอนสตรคเตอรตวพนใหละเอยด
กสามารถถกตวอนเรยกใชไดหมด จะไดกสามารถถกตวอนเรยกใชไดหมด จะได
ประหยดเวลาในการเขยนคอนสตรคเตอรตวหลงๆ
Initialization block อนนเราอยในคลาส Initialization blockprivate int id;private String name = ""; // instance field initialization
อนนเราอยในคลาส
Employee นะprivate String name ; // instance field initializationprivate double salary;
// static initialization blockstatic ก initialize ไดตรงนเหมอนกน
// static initialization blockstatic{R d R d ()
ใช initialize static i blRandom generator = new Random();
// set nextId to a random number between 0 and 9999nextId = generator.nextInt(10000);
variable แตตามปกตใชกบการ initialize ทคอนขางซบซอนเทานน
}
// object initialization block
คอนขางซบซอนเทานน
j{id = nextId;nextId++;
Execute เมอออบเจกตของคลาสนถกสราง ซงตวโคดนจะถกรนกอนคอนสตรคเตอรnextId++;
}ซงตวโคดนจะถกรนกอนคอนสตรคเตอร
ป • ลาดบการรนจะเปนดงน
– ตอนแรกคาทกคาเปน default– Field initializer และ initialization block จะถกรน ตามลาดบ
บรรทดในโคดวาอนไหนจะมากอนมาหลง (static initialization กทาตามลาดบนเหมอนกน)ตามลาดบนเหมอนกน)
– ถาบรรทดแรกของคอนสตรคเตอร เปนการเรยกคอนสตรคเตอรอกตว คอนสตรคเตอรตวทถกเรยกจะโดนรนกอนเตอรตวทถกเรยกจะโดนรนกอน
– คอนสตรคเตอร
• มาดตวอยางโปรแกรมทใชคอนสตรคเตอรกน มาดตวอยางโปรแกรมทใชคอนสตรคเตอรกน ConstructorTest.java
packagespackages
k• กลมของคลาสทใชดวยกน เรยกวา package• ในจาวาเองกม
– java.lang
j il– java.util
– java.net• เราจดแพคเกจเองได จดเหมอนกบการจดโฟลเดอรทเกบไฟล
• ทมมาใหเราแลว จะอยใน java หรอ javax• ทมมาใหเราแลว จะอยใน java หรอ javax
• ทาไมตองม package– เหตผลสาคญคอ จะไดไมมปญหาการทคลาสชอซากน
– สมมตมคนคดคลาส Employee มาสองคน ถาตางคนตางเอาเขา – สมมตมคนคดคลาส Employee มาสองคน ถาตางคนตางเอาเขา
package คนละอน จาวากจะรวาเปนคนละคลาสกน ไมสบสนวามชอซา
k ใ – แตทงน ชอ package กตองตงใหตางกนดวย• เพอทจะทาใหไดชอเฉพาะมากๆ sun ใหใชชอเวบไซตกลบหลง เชน
i hcom.vishnu• จากนนกสามารถทา subpackage ตอได เชน com.vishnu.progmeth
l l • สาหรบจาวาเอง java.util กบ java.util.jar ถอวาเปนสองแพกเกจทไมมอะไรเกยวของกนเลย
การ importการ import
ใ ใ ใ• คลาสหนงๆ สามารถใชงานคลาสทอยในแพกเกจเดยวกน และคลาสในแพกเกจอนทเปน public
• แตวา คลาสในแพกเกจอน จะมองไมเหน ตองมการบอก โดยมสองวธ
– ใสชอแพกเกจขางหนาชอคลาสทกคลาสทเอามาจากแพกเกจอน เชน
Java.util.Date today = new java.util.Date();• แตวธนมนทาใหเขยนยดยาวแตวธนมนทาใหเขยนยดยาว
– วธทสองคอการ import• เขยน import ดานบนของไฟล ตอจากนยามpackage ทเรานยาม packageเขยน import ดานบนของไฟล ตอจากนยามpackage ทเรานยาม package ของคลาส
• import java.util.*; จะเปนการอมพอรตทกไฟลจากแพกเกจนน
• แตวา ใชงานแบบนไมได
import java.*;
import java * *;import java. . ;
• และทตองระวงอกอยางคอ ถาสองแพกเกจดนมคลาสชอเหมอนกน เชน
java.util.* กบ java.sql.* มคลาส Date ทงค– ถาเราอมพอรตทงค เราจะใช Date ไมได
– แกโดย import java util Date; เขยนอนนลงไปเพมแกโดย import java.util.Date; เขยนอนนลงไปเพม
– หรอ ถาเกดตองใช Date จากทงสองคลาสจรงๆ กตองเขยนชอคลาสทรวมชอแพกเกจดวยตลอดชอแพกเกจดวยตลอด
Static importStatic import
i i j l S *import static java.lang.System.*;
จะทาใหเรยกใช static เมธอด และ static field จากคลาส System ได โดยไมตองเอยชอคลาสกอน เชน
out println(“ ”);out.println( … );
ใ ไ M th ใ t t ใ ไ ปใชไดดกบคลาส Math และการใชงาน constant เพราะใชไดอยางเปนธรรมชาตมากขน
การนยามวาคลาสเรา อยในแพกเกจอะไรการนยามวาคลาสเรา อยในแพกเกจอะไร
f l• ใสชอแพกเกจ ดานบนสดของ source file ตวอยางเชน
package com.vishnu.progmeth;package com.vishnu.progmeth;
public class Employee{……
}
ถาเราไมใสชอแพกเกจใหคลาสเรา จาวาจะถอวา คลาสนนอยใน
default package
การเกบไฟลในโฟลเดอรการเกบไฟลในโฟลเดอร
ไป ไฟ ใ โฟ • เมอเรานยามแพกเกจไปแลว การเกบไฟลในโฟลเดอรของคอมพวเตอร
เรา กตองทาตามชอของแพกเกจ เชน
• ไฟลทงหมดทอยในแพกเกจ com.vishnu.progmeth จะตอง
ถกเกบในโฟลเดอร com\vishnu\progmeth ซงตองอยใน ถกเกบในโฟลเดอร com\vishnu\progmeth ซงตองอยใน
base directory อกทหนง
• ตองเกบใหถก เพราะวา .class ไฟลจะถกเกบไวตามนเหมอนกน ถา
เกด source file ไมไดอยตามโฟลเดอรน จะคอมไพลไดแตรนไมได
เพราะการหา .class ไฟล จะหาจากโฟลเดอรทเรานยามแพกเกจ
Package scopePackage scope
ไ ไ bl • ถาเราไมไดบอกวา คลาส ตวแปร หรอเมธอด เปน public หรอ
private จาวาจะถอวา เมธอดอนๆ ทอยในแพกเกจเดยวกน จะสามารถมองเหนคลาส ตวแปร หรอเมธอดนนได
• เราสามารถ seal package ได• เราสามารถ seal package ได– เปนการปองกน ไมใหคนอนมาเตมไฟลลงใน แพกเกจของเรา
– ทาโดยการ seal jar (จะเหนวา eclipse จะมคาสงพวกนในตว)
Class pathClass path
f l ไ ไ• Jar file คอ zip ไฟล ทเกบคลาสไฟลตางๆ และเกบ
subdirectory ไว
• เราตองตงคา classpath
\ l di \ hi \ hi j
ใช * ได
c:\classdir;.;c:\archives\archive.jar
Base directory Jar file
Current directory
• เวลาจาวาจะหาคลาส มนจะดทตว library ของมนกอน
• แลวคอยมาด class path• สมมตเรามคลาสคลาสหนงทอมพอรตดงน
import java.util.*;i i h h *import com.vishnu.progmeth.*;
ถาในไฟลนมการใชงาน คลาส Employee จาวาจะพยายามไปดJava lang Employee java util EmployeeJava.lang.Employee, java.util.Employee, com.vishnu.progmeth.Employee และ Employee ใน current package โดยจะหาแตละไฟลพวกน จากทกๆใน current package โดยจะหาแตละไฟลพวกน จากทกๆโฟลเดอรทนยามใน class path