เนื้อหาตอนต่อไปนี้ เราจะดูเกี่ยวกับการใช้งาน static variable และ
static method ในภาษา Dart
ก่อนเอื่นเราทำความเข้าใจภาษา Dart นั้นรองรับการใช้งาน top-level function
(เช่น ฟังก์ชั่น main() ) และฟังก์ชั่นของ class หรือฟังก์ชั่นของ object
(ฟังก์ชันระดับ class จะเรียกว่า static method ในขณะที่ฟังก์ชั่นของ object จะเรียกว่า
instance method ดูรายละเอียดเพิ่มเติมตามหัวข้อต่อไปนี้
การใช้งาน Static Method
Static method เป็นฟังก์ชั่นที่กำหนดโดยใช้ keyword คำว่า static กำกับไว้ด้านหน้าของฟังก์ชั่น
โดยปกติกำหนดคล้ายๆ กับฟังก์ชั่นปกติทั่วไปใน class เช่นเดียวกับ instance method แต่ด้วยลักษณะของ
ฟังก์ชั่น static ที่สร้างขึ้นมาเพื่อใช้งานอรรถประโยชน์ มากกว่าที่จะให้ความสำคัญกับ object โดยตรง หรือใน
บางครั้ง อาจจะไม่มีความเกี่ยวข้องกับตัว object เลยก็ได้ ดังนั้นฟังก์ชั่น static จึงไม่สามารถเรียกใช้งานผ่าน
instance object ได้ แต่จะเรียกใช้งานผ่านระดับ class หรือ class name ดูตัวอย่างโค้ดด้านล่างประกอบ
void main () { var car1 = Car('red',2000); // การเรียกใช้ instance method สามารถเรียกใช้งานผ่าน // instance object ได้ car1 คือ instance object print(car1.getColor()); var car2 = Car('blue',1500); print(car2.getColor()); // การเรียกใช้ static method ต้องเรียกใช้งาน // ผ่าน class name ไม่สามารถเรียกใช้งานผ่าน instance object print(Car.comparePrice(car1, car2)); } class Car{ String color; int price; Car(this.color,this.price); // instnce method String getColor(){ return color; } // static method static int comparePrice(car1, car2){ return car1.price - car2.price; } }
สังเกต Car class เรากำหนดฟังก์ชั่น 2 ตัวคือ getColor() ซึ่งเป็น instance method และ comparePrice() ซึ่งเป็น static method โดยมี
keyword static กำกับไว้ด้านหน้า เป็นฟังก์ชั่นอรรถประโยชน์หรือเครื่องมือ ที่ใช้ในการเปรียบราคาของ รถยนต์ 2 คัน
ในการเรียกใช้งาน กรณีที่เป็น instance method เราสามารถสร้าง object หรือที่เรียกว่า ตัวแปร instance object มาเรียกใช้งานได้ อย่างตัว
อย่างข้างต้น เราสร้างตัวแปร car1 เป็น instance object แล้วเรียกใช้งาน instance method หรือฟังก์ชั่น getColor() ในรูปแบบ car1.getColor();
แต่สำหรับฟังก์ชั่น comparePrice() ซึ่งเป็น static method เราไม่สามารถใช้ตัวแปร car1 เรียกใช้งานในลักษณะ car1.comparePrice() แต่สามารถ
เรียกใช้งานผ่าน class name ในลักษณะ Car.comparePrice() ได้ ดังตัวอย่างด้านบน
จะเห็นว่าเราสร้าง static method ไว้สำหรับใช้งานเฉพาะ ที่อาจจะไม่ได้สัมพันธ์กับ instance object ทั้งนี้ก็เพื่อให้บางกรณี เราต้องการฟังก์ชั่นนั้นๆ
ไว้ใช้งาน แต่ไม่ต้องการให้ผูกกับ instance object เพื่อลดการใช้งานหน่วยความจำให้กับการเรีรยกใช้งานฟังก์ชั่น นั่นคือฟังก์ชั่น static จะไม่ใช้งาน
หน่วยความจำจนกว่าจะมีการเรียกใช้งาน และจะใช้งานแค่ครั้งเดียวเท่านั้น ดูคำอธิบายการใช้งานหน่วยความจำสำหรับ การเรียกใช้งาน instance method
กับ static method จากตัวอย่างด้านล่าง
void main () { var car1 = Car('red',2000); // ใช้งานหน่วยความจำทุกๆ instnce object ที่เรียกใช้งาน print(car1.getColor()); var car2 = Car('blue',1500); // ใช้งานหน่วยความจำทุกๆ instnce object ที่เรียกใช้งาน print(car2.getColor()); // ใช้งานหน่วยความจำแค่ครั้งแรก print(Car.comparePrice(car1, car2)); var car3 = Car('black',500); // ใช้งานหน่วยความจำทุกๆ instnce object ที่เรียกใช้งาน print(car3.getColor()); // ใช้งานจากหน่วยความจำครั้งแรก ไม่มีการใช้งานเพิ่ม print(Car.comparePrice(car1, car3)); }
getColor() เป็นฟังก์ชั่นที่มีการใช้งานหน่วยความจำทุกๆ ครั้งที่ instance object เรียกใช้งานฟังก์ชั่น ในขณะที่ comparePrice() ซึ่งเป็น static method
จะมีการใช้งานหน่วยความจำเฉพาะการเรียกใช้งานครั้งแรก และจะใช้ค่าจากหน่วยความจำเดิม สำหรับการเรียกใช้งานครั้งต่อๆ ไป
การใช้งานระหว่าง static และ instance method
ต่อไปเรามาดูว่า ถ้าเรามีการเรียกใช้งาน static method และ instance method ภายใน class จะสามารถทำได้หรือไม่ โดยสมมติเราลองสร้างฟังก์ชั่น
ต่อไปนี้ เพื่อเรียกใช้ instance method ภายใน static method ดังนี้
class Car{ String color; int price; Car(this.color,this.price); // instnce method String getColor(){ return color; } // static method static int comparePrice(car1, car2){ return car1.price - car2.price; } // error ตัวอย่างฟังก์ชั่นไม่สามารถกำหนดได้ static int getPrice(){ this.getColor(); // error ไม่สามารถเรียกใช้งาน instance method ได้ return this.price; // error ไม่สามารถเรียกใชงาน instance variable ได้ } }
จะเห็นว่า เราลองสร้างฟังก์ชั่น static ขึ้นมา แล้วเรียกใช้งาน instance method กับ instance variable ภายใน static method จะเกิด error ขึ้น
โดยเราไม่สามารถใช้งาน this ในฟังก์ชั่น static ได้ นั่นคือเราไม่สามารถเรียกใช้งาน ตัวแปรและฟังก์ชั่น instanceใน static ฟังก์ชั่นได้ ต่อไป เราลองในทาง
ตรงกันข้าม คือเรียกใช้ static method ภายใน instance method ดูว่า ทำได้หรือไม่ ดังนี้
void main () { var car1 = Car('red',2000); print(car1.getPrice()); // output: 10000 } class Car{ String color; int price; Car(this.color,this.price); // instnce method int getPrice(){ // เรียกใช้ static method ใน instance method ได้ปกติ return Car.maxPrice(); // หากอยู่ใน class สามารถละ ชื่อ class ได้ // return maxPrice(); } // static method static int maxPrice(){ return 10000; } }
จะเห็นว่าในฟังก์ชั่นทั่วไปหรือ instance method เราสามารถเรียกใช้งาน static method ได้ ซึ่งถ้าอยู่ใน class เดียวกัน เราสามารถละ ชื่อ class
เช่น ใช้งาน return maxPrice() แทน return Car.maxPrice() ได้
การใช้งาน Static variable
เช่นเดียวกับการใช้งาน static method โดย static variable เป็น top-level variable โดยในระดับ class เราจะเรียกว่า static variable หรือใน
กรณีเป็น object จะเรียกว่า instance variable ดูตัวอย่างโค้ดด้านล่างประกอบการทำความเข้าใจ
void main () { var circle1 = Circle(22); // ใช้งานหน่วยความจำทุกๆ instnce object ที่เรียกใช้งาน print(circle1.pi); var circle2 = Circle(44); // ใช้งานหน่วยความจำทุกๆ instnce object ที่เรียกใช้งาน print(circle2.pi); } class Circle{ double radius; // instance variable double pi = 3.14; // instance variable Circle(this.radius); // constructor // instance method double getArea(){ return pi * (radius * radius); } }
สังเกตการเรียกใช้งานตัวแปร pi หรือ instance variable ที่ทุกๆ ครั้งที่มีการเสร้าง object และเรียกใช้งาน ตัวแปร pi จะมีการดึงหน่วยความจำมาใช้
ซึ่งจะเห็นว่า ค่า pi เป็นค่าคงที่ไม่เปลี่ยนแปลง เราสามารถกำหนดตัวแปรนี้เป็น static variable เพื่อให้รองรับการเรียกใช้งานหน่วยความจำแค่ครั้งแรก
ครั้งเดียวได้ เช่นเดียวกับวิธีของ static method โดยใช้ keyword คำว่า static กำกับไว้ด้านหน้าของตัวแปร ดังนี้
void main () { var circle1 = Circle(22); // print(circle1.pi); // error ไม่สามารถเรียกใช้ผ่าน instance ได้ print(Circle.pi); // สามารถเรียกใช้ผ่าน class name ได้ // โดยจะใช้งานหน่วยความจำแค่ครั้งแรกครั้งเดียว var circle2 = Circle(44); // print(circle2.pi); // error ไม่สามารถเรียกใช้ผ่าน instance ได้ print(Circle.pi); // สามารถเรียกใช้ผ่าน class name ได้ // การเรียกใช้ครั้งที่สองจะใช้จากค่าเดิม จะไม่มีการใช้งานหน่วยความจำเพิ่ม } class Circle{ double radius; // instance variable static double pi = 3.14; // static variable Circle(this.radius); // constructor // instance method double getArea(){ // ตัวแปร pi เป็น static variable // สามารถเรียกใช้งานใน ฟังก์ชั่นปกติได้ return pi * (radius * radius); } // static method static double getPi(){ // ตัวแปร pi เป็น static variable // สามารถเรียกใช้งานใน ฟังก์ชั่น static ได้ return pi; } // static method static void testStatic(){ getPi(); // เรียกใช้ static method ได้ print(pi); // เรียกใช้งาน static variable ได้ } }
จะเห็นตอนนี้เราเปลี่ยนตัวแปร pi เป็นตัวแปร static หรือ static variable โดยตัวแปร static variable จะไม่สามารถเรียกใช้งานผ่าน instance ได้
ในลักษณะเช่นเดียวกับ static method ตามที่เราอธิบายไปในหัวข้อก่อนหน้า เราสามารถเรียกใช้งานตัวแปร static ในระดับ class name ซึ่งจริงๆ แล้ว
ตัวแปร static จะเหมาะกับการกำหนดค่าให้กับตัวแปรค่าคงที่ เป็นตัวแปรในลักษณะ top-level variable ที่สามารถเรียกใช้งานผ่าน class ใดๆ ในโปรแกรม
ได้ โดยจะมีการใช้งานหน่วยความจำแค่ครั้งแรกที่มีการเรียกใช้ และใช้ค่าจากหน่วยความจำเดิม ในการเรียกใช้งานในครั้งต่อไป
นอกจากตัวอย่างการใช้งาน static variable ผ่าน class name เรายังทดสอบการเรียกใช้งานตัวแปร static จากฟังก์ชั่นปกติ getArea() จะเห็นว่า
เราสามารถเรียกใช้งาน static variable ภายใน instance method ได้ เช่นเดียวกับ เราสามารถเรียกใช้งาน static variable จาก static method จาก
ตัวอย่าง ฟังก์ชั่น getPi() และ testStatic() เป็น static method ที่มีการเรียกใช้งาน static variable ได้
ก่อนจบขอสรุป การเรียกใช้งาน static variable และ static method ดังนี้ ประกอบการทบทวนทำความเข้าใจ
* ภายใน Static method
- สามารถเรียกใช้งาน ได้เฉพาะ static variable และ static method เท่านั้น ไม่สามารถเรียกใช้งาน instance variable
และ instance method ใน static method ได้
* ภายใน Instance method
- สามารถเรียกใช้งาน ตัวแปรและฟังก์ชั่นทุกตัวใน class ได้ ทั้ง static และ instance
* การเรียกใช้ static variable และ static method ใน class เดียวกัน สามารถเรียกใช้ผ่าน class name หรือไม่กำหนด class name ก็ได้
* การเรียกใช้ static variable และ static method นอก class จะเรียกใช้งานผ่าน class name เท่านั้น เช่น การเรียกใช้งาน main() ฟังก์ชั่น
* การเรียกใช้ static variable และ static method จะใช้งานหน่วยความจำเมื่อมีการทำงานครั้งแรกเท่านั้น จะคืนค่าหน่วยความจำเมื่อโปรแกรม
ปิดหรือหยุดการทำงาน
* การเรียกใช้ static variable และ static method ไม่สามารถเรียกใช้งานผ่าน instance object ได้