การสร้างเว็บเพจโดยใช้ภาษา
PHP บทที่ 32
การสร้างและใช้งานคลาส
(class) และออปเจค (object)
ภาษาแบบ
scripting language ในปัจจุบันหลายๆภาษาก็สนับสนุนการเขียนโปรแกรมเชิงวัตถุด้วย
ตัวอย่างเช่น Perl และ PHP ก็รวมอยู่ในนั้นด้วย แม้ว่าจะไม่ซับซ้อนเหมือนอย่างภาษาซีพลัสพลัสหรือจาวาก็ตาม
คลาสคือโครงสร้างที่ประกอบด้วยสมาชิก
(class members) หรือคุณสมบัติ (properties) ตามแต่จะเรียก และ ฟังก์ชันสมาชิก
(member functions) การนิยามคลาสขึ้นมาใช้งานจะเริ่มด้วย class {
... } โดยข้างในจะมีส่วนของตัวแปรสมาชิก และฟังก์ชันสมาชิกตามลำดับ
ฟังก์ชันที่มีชื่อเดียวกับคลาสจะเรียกว่า class constructor ทุกครั้งที่มีการสร้างออปเจคจากคลาสโดยใช้คำสั่ง
new ฟังก์ชันที่ทำหน้าที่เป็น class constructor ก็จะถูกเรียกมาทำงานก่อนทุกครั้ง
ประโยชน์ของการใช้งานก็เช่น ใช้กำหนดค่าเริ่มต้น หรือเตรียมพร้อมก่อนที่จะเริ่มใช้ออปเจค
ลองดูตัวอย่าง
การเขียนคลาสสำหรับแบบข้อมูลเชิงนามธรรม (Abstract Data Type) ที่เรียกว่า
stack การทำงานของ stack ก็เป็นดังนี้ ถ้าเราใส่ข้อมูลเข้าไป ข้อมูลเหล่านั้นก็จะถูกเก็บไว้เสมือนกับว่า
วางซ้อนกันจากข้างล่างขึ้นข้างบน ถ้าเราจะดึงข้อมูลออกมาใช้ก็จะได้ข้อมูลที่อยู่ข้างบนสุด
ซึ่งก็คือข้อมูลที่เราใส่เข้าไปครั้งล่าสุดนั่นเอง หน้าที่ของ stack
ที่สำคัญก็มีเช่น
| push() |
ใส่ข้อมูลไว้ใน
stack |
| pop() |
ดึงข้อมูลออกมา |
| is_empty() |
ตรวจดูว่า
stack มีข้อมูลอยู่อีกหรือไม่ |
| get_size() |
หาจำนวนของข้อมูลที่ถูกเก็บไว้ใน
stack |
ตัวอย่างการสร้างคลาส
stack ในภาษา PHP ทำได้ดังตัวอย่างต่อไปนี้
| <?
class stack {
var $arrays;
var $size;
function stack() { // class constructor
$this->size = 0;
unset($this->arrays);
}
function push($elem) { // put an
element on stack
$this->arrays[$this->size]
= $elem;
$this->size++;
}
function get_size() { // get number
of elements stored
return $this->size;
}
function is_empty() { // is stack empty
?
return ($this->size == 0)
? true : false;
}
function pop() { // retrieve an element
from the top of stack
if ( $this->is_empty() ==
false ) {
$this->size--;
return $this->arrays[$this->size];
}
else
return 0;
}
}
$inst = new stack; // create an object from stack
class
echo "initial stack size=".($inst->get_size()),"<BR>\n";
for ($i=0; $i < 10; $i++) {
$inst->push( ($i*7)%11 );
}
echo "current stack size=".($inst->get_size()),"<BR>\n";
while (! $inst->is_empty() ) {
echo "pop ".$inst->pop(),"<BR>\n";
}
echo "stack is ".($inst->is_empty() ? "empty." : "not
empty.")."<BR>\n";
$inst = 0; // unuse this instance of class stack
?> |
โปรดสังเกตว่า
ตัวแปร $this ที่ปรากฎอยู่ในคลาสจะเหมือน this ที่เราใช้ในภาษาซีพลัสพลัส
และการนิยามและสร้างฟังก์ชันสมาชิกจะทำภายในคลาสทั้งหมด (เหมือนในภาษาจาวา)
PHP
ยังสนับสนุนการสืบทอดคุณสมบัติของคลาส (inheritance) ทำให้เราสามารถสร้างคลาสขึ้นมาใหม่
โดยใช้คลาสที่มีอยู่เดิมและเพื่อส่วนขยายเข้าไป การสืบสอดคุณสมบัติจากคลาสหนึ่งไปยังอีกคลาสหนึ่ง
จะใช้คำสั่ง extends คล้ายกับของภาษาจาวา ตามตัวอย่างดังนี้
| <?
class stack {
var $arrays;
var $size;
function stack() {
echo "DEBUG> stack constructor<BR>\n";
$this->size = 0;
unset($this->arrays);
}
function push($elem) {
$this->arrays[$this->size]
= $elem;
$this->size++;
}
function get_size() {
return $this->size;
}
function is_empty() {
return ($this->size == 0)
? true : false;
}
function pop() {
if ( $this->is_empty() ==
false ) {
$this->size--;
return $this->arrays[$this->size];
}
else
return 0;
}
}
// class LimitedStack is derived from class stack.
class LimitedStack extends stack {
var $max_size;
function LimitedStack ($capacity = 10)
{
$this->stack(); //
call stack's constructor explicitly.
echo "DEBUG> LimitedStack
constructor<BR>\n";
$this->max_size =
$capacity;
}
function is_full() {
return ($this->max_size
<= $this->size) ? true : false;
}
function push($elem) {
if ($this->is_full() ==
false) {
$this->arrays[$this->size]
= $elem;
$this->size++;
}
else {
echo "stack
is full!\n";
}
}
}
$inst = new LimitedStack(5);
echo "initial stack size=".($inst->get_size()),"<BR>\n";
for ($i=0; $i < 10; $i++) {
if (! $inst->is_full() ) {
$inst->push( ($i*7)%11 );
}
else break;
}
echo "current stack size=".($inst->get_size()),"<BR>\n";
echo "stack is ".($inst->is_empty() ? "empty." :
"not empty.")."<BR>\n";
|
คลาส
LimitedStack นี้มีคุณสมบัติที่ได้รับมาจากคลาส stack แต่แตกต่างตรงที่ว่า
เราได้กำหนดความจุ ของ LimitedStack เอาไว้ โดยตัวแปร $max_size
ผู้ใช้จะต้องกำหนดขนาดความจุของออปเจคจากคลาส LimitedStack ก่อนใช้
ถ้าไม่กำหนดก็จะใช้ค่า 10 เป็นค่าความจุโดยอัตโนมัติตามตัวอย่าง
(เป็น default parameter)
เมื่อมีการกำหนดความจุก็จะต้องมีการเขียนฟังก์ชันสมาชิกเพิ่มขึ้นอีก
ชื่อ is_full() เพื่อตรวจสอบดูว่า จำนวนของข้อมูลใน stack
เท่ากับความจุที่กำหนดไว้แล้วหรือไม่
โปรดสังเกตว่า
PHP สนับสนุนการนิยามฟังก์ชันทับฟังก์ชันเดิมของคลาสที่ได้รับคุณสมบัติมา
และสิ่งที่จะลืมไม่ได้คือ constructor จากคลาสลูก (child class)
จะไม่เรียกใช้ constructor จากคลาสแม่ (parent class) จะต้องมีการเรียกใช้อย่างเจาะจง
ในกรณีที่เราสร้างอาร์เรย์สำหรับเก็บออปเจค
เวลาจะใช้ออปเจคแต่ละตัว จะต้องใช้ตัวแปรช่วยตามตัวอย่างต่อไปนี้
<?
// array of objects
class MyObj {
var $id;
function MyObj( $set_id) {
// $id = $set_id; <-- this does't
work if you forget to use $this
$this->id = $set_id;
}
function show() {
echo "hello world $this->id<BR>\n";
}
}
// can create the array of objects
$obj_array = array();
$obj_array[] = new MyObj(1);
$obj_array[] = new MyObj(2);
$obj_array[] = new MyObj(3);
// To access each object we must use help variable
like follows:
for($i=0; $i < count($obj_array); $i++) {
$tmp = $obj_array[$i];
$tmp->show();
}
?> |
จากตัวอย่างเราใช้ตัวแปร
$tmp ในการเข้าถึงออปเจคแต่ละตัวในถูกเก็บไว้ในอาร์เรย์ $obj_array
เนื่องจากเราไม่สามารถเรียกใช้ฟังก์ชันของออปเจคได้โดยตรงถ้าออปเจคอยู่ในอาร์เรย์
เช่น $obj_array[0]->show();
|