public, private, และ protected ใน PHP OOP

เวลาที่เราเขียนคลาสในภาษา PHP เราสามารถกำหนดให้ตัวแปรและฟังก์ชั่นภายในคลาสได้ (รู้สึกว่าเค้าจะเรียกกันว่า method) ว่าจะให้สามารถเรียกใช้ได้จากที่ไหนได้บ้าง  ซึ่งเราเรียกมันว่า Visibility ครับ  โดยเราสามารถกำหนดได้อยู่ 3 แบบคือ

  1. public สามารถเรียกได้ทุกที่  ทั้งภายในและภายนอกคลาส
  2. private สามารถเรียกได้เฉพาะในคลาส
  3. protected สามารถเรียกได้เฉพาะในคลาส และคลาสที่ขยายคลาสนี้

เราสามารถสรุปเรื่อง visibility ได้สั้นๆดัง 3 ข้อด้านบนครับ  ถ้าเข้าใจก็เรียกได้ว่าจบเนื้อหาตอนนี้  แต่ถ้ายังไม่เข้าใจ  ลองไปดูตัวอย่างยาวๆ กันครับ

ตัวอย่างนี้จะเป็นโค๊ดของคลาสสองตัว  โดยตัวที่หนึ่งจะมีการสร้างฟังก์ชั่นภายในเอาไว้สามตัว  เป็นทั้ง public, private, และ protected ส่วนคลาสที่สองจะมาขยาย (extends) คลาสแรก  เพื่อทดสอบการเรียกใช้ฟังก์ชั่นแบบ protected ครับ

<?
class helloworld {

	public function myPublicFunc (){
		return "I am Public!";
	}

	private function myPrivateFunc (){
		return "I am Private!";
	}

	protected function myProtectedFunc (){
		return "I am Private!";
	}

	function output (){
		echo "Public Function: ".$this->myPublicFunc()."<br/>";
		echo "Private Function: ".$this->myPrivateFunc()."<br/>";
		echo "Protected Function: ".$this->myProtectedFunc()."<br/>";
	}
}

class hellomars extends helloworld {
	function __construct(){
		echo "Public Function: ".$this->myPublicFunc()."<br/>";
		echo "Protected Function: ".$this->myProtectedFunc()."<br/>";
		echo "Private Function: ".$this->myPrivateFunc()."<br/>";
	}
}
?>

ตัวอย่างโค๊ดด้านบน  จะเห็นว่ามีการกำหนด visibility ให้กับฟังก์ชั่นภายในทั้ง 3 ตัว คือ

  1. myPublicFunc() กำหนดเป็น public คือสามารถเรียกใช้ได้จากในทุกๆที่  ทั้งในคลาส  และนอกคลาส
  2. myPrivateFunc() กำหนดเป็น private คือจะสามารถเรียกใช้ได้ภายในคลาสนี้เท่านั้น
  3. myProtectedFunc() กำหนดเป็น protected คือจะสามารถเรียกใช้ได้ภายในคลาสนี้  และคลาสที่ขยายคลาสนี้เท่านั้น (ในตัวอย่างคือคลาส hellomars)

จากโค๊ดข้างบน  จะเห็นว่าผมสร้างฟังก์ชั่น output() เอาไว้ภายในคลาส helloworld ซึ่งเป็นการเรียกใช้ฟังก์ชั่นอื่นๆทั้งหมดภายในคลาสนี้  ซึ่งเมื่อเราลองรันด้วยโค๊ดด้านล่างนี้

echo "<h1>Inside Class</h1>";
$myclass = new helloworld();
$myclass->output();

ผลก็จะออกมาดังภาพนี้ครับ

ในขั้นตอนนี้จะสามารถรันได้ปกติไม่มีปัญหาอะไร  เพราะ

  1. myPublicFunc() เป็น public สามารถเรียกได้จากทุกที่  แน่นอนว่ารวมทั้งในคลาสด้วย
  2. myPrivateFunc() เป็น private สามารถเรียกได้เฉพาะภายในคลาสนั้นๆ
  3. myProtected() เป็น protected สามารถเรียกได้เฉพาะภายในคลาสนี้ และคลาสที่ขยายคลาสนี้

เพื่อให้เห็นภาพชัดขึ้น  เราจะลองเรียกใช้ตัวแปรแต่ละตัวจากนอกคลาสดู  ด้วยโค๊ดชุดนี้

echo "<h1>Outside Class</h1>";
echo "Public Function: ".$myclass->myPublicFunc()."<br/>";
echo "Protected Function: ".$myclass->myProtectedFunc()."<br/>";

และชุดนี้

echo "<h1>Outside Class</h1>";
echo "Public Function: ".$myclass->myPublicFunc()."<br/>";
echo "Private Function: ".$myclass->myPrivateFunc()."<br/>";

ผมต้องขอแยกโค๊ดเป็นสองชุดนะครับ  เพื่อให้เห็น Error ชัดเจน (มันเป็น fatal error ซึ่งมันจะหยุดสคริปท์ไปเลย  ดังนั้นเลยต้องแยกโค๊ดกัน  เพื่อให้เห็น error ทั้งหมด)

ผลลัพธ์ของโค๊ดทั้งสองชุดด้านบน  จะออกมาในลักษณะเดียวกันคือสามารถเรียกใช้ myPublicFunc() ได้  แต่ฟังก์ชั่นอื่นจะ Error ทั้งหมด  นั้นเป็นเพราะว่า private และ protected ไม่สามารถเรียกใช้จากภายนอกคลาสได้นั่นเองครับ

และส่วนสุดท้ายคือ protected function ที่สามารถเรียกใช้งานได้จากในคลาสที่ขยายคลาสนั้นๆ ด้วย  ซึ่งจากโค๊ดตัวอย่างด้านบน  ผมได้เตรียมคลาส hellomars ที่ขยายคลาส helloworld เอาไว้แล้ว

ปกติแล้วการขยายคลาส (extend) จะทำให้คลาสใหม่ที่เขียนขึ้น  สามารถเรียกใช้ตัวแปรและฟังก์ชั่นประเภท public และ protected จากคลาสเดิมได้ด้วย  แต่จะไม่สามารถเรียกใช้ตัวแปรและฟังก์ชั่นแบบ private จากคลาสเดิมได้  ซึ่งถ้าเราลองสร้างออพเจ็กท์ใหม่ขอคลาส hellomars ขึ้นมาด้วยโค๊ดชุดนี้

echo "<h1>In Extended Class</h1>";
$myclass = new hellomars();

และจากโค๊ดตัวอย่าง  จะมีการเรียกใช้ฟังก์ชั่นทั้งสามตัวจากคลาส helloworld อยู่ภายในฟังก์ชั่น constructor ดังนั้น  เมื่อเราสร้างออพเจ็กท์  มันก็จะเกิดผลลัพธ์ดังนี้

จะเห็นได้ว่าเราสามารถเรียกใช้ฟังก์ชั่นที่เป็น public และ protected ได้เป็นปกติ  แต่จะไม่สามารถเรียกใช้ฟังก์ชั่นที่เป็น private ได้

แน่นอนว่านอกจากฟังก์ชั่นภายใน (ที่ปกติค้าจะเรียกกันว่า Method) และตัวแปร  เราสามารถกำหนด Visibility ให้มันได้ทั้งหมด  ซึ่งก็อยู่แล้วแต่โอกาสว่าอะไรควรกำหนดเป็นอะไร  ซึ่งถ้าเราไม่กำหนดว่ามันมี visibility เป็นอะไร  ตัว php จะกำหนดให้เองอัตโนมัติว่ามันเป็น public ครับ

Posted by Jirayu

WordPress Developer ที่พอมีประสบการณ์อยู่บ้าง วันไหนไม่ทำงานอยู่บ้านว่างๆ ก็นั่งเลี้ยงแมว

Comments