การเขียนโปรแกรมเชิงวัตถุใน PHP
เราสามารถจินตนาการถึงจักรวาลของเราที่สร้างจากวัตถุต่างๆเช่นดวงอาทิตย์โลกดวงจันทร์เป็นต้นในทำนองเดียวกันเราสามารถจินตนาการว่ารถของเราทำจากวัตถุต่าง ๆ เช่นล้อพวงมาลัยเกียร์ ฯลฯ ในทำนองเดียวกันมีแนวคิดการเขียนโปรแกรมเชิงวัตถุซึ่งถือว่าทุกสิ่งทุกอย่างเป็นวัตถุและ ใช้ซอฟต์แวร์โดยใช้วัตถุที่แตกต่างกัน
แนวคิดเชิงวัตถุ
ก่อนที่เราจะดูรายละเอียดให้กำหนดคำศัพท์สำคัญที่เกี่ยวข้องกับ Object Oriented Programming
Class- นี่คือประเภทข้อมูลที่โปรแกรมเมอร์กำหนดซึ่งรวมถึงฟังก์ชันในเครื่องและข้อมูลในเครื่อง คุณสามารถคิดว่าคลาสเป็นเทมเพลตสำหรับการสร้างอินสแตนซ์ (หรือคลาส) ของออบเจ็กต์เดียวกันจำนวนมาก
Object- อินสแตนซ์ส่วนบุคคลของโครงสร้างข้อมูลที่กำหนดโดยคลาส คุณกำหนดคลาสหนึ่งครั้งแล้วสร้างอ็อบเจกต์จำนวนมากที่เป็นของคลาสนั้น ออบเจ็กต์เรียกอีกอย่างว่าอินสแตนซ์
Member Variable- นี่คือตัวแปรที่กำหนดไว้ภายในคลาส ข้อมูลนี้จะมองไม่เห็นจากภายนอกชั้นเรียนและสามารถเข้าถึงได้ผ่านฟังก์ชันของสมาชิก ตัวแปรเหล่านี้เรียกว่าแอตทริบิวต์ของวัตถุเมื่อสร้างวัตถุ
Member function - นี่คือฟังก์ชันที่กำหนดไว้ภายในคลาสและใช้เพื่อเข้าถึงข้อมูลออบเจ็กต์
Inheritance- เมื่อคลาสถูกกำหนดโดยการสืบทอดฟังก์ชันที่มีอยู่ของคลาสพาเรนต์จะเรียกว่าการสืบทอด คลาสย่อยจะสืบทอดฟังก์ชันสมาชิกทั้งหมดหรือสองสามตัวของคลาสแม่
Parent class- คลาสที่สืบทอดมาจากคลาสอื่น เรียกอีกอย่างว่าคลาสพื้นฐานหรือซูเปอร์คลาส
Child Class- คลาสที่สืบทอดมาจากคลาสอื่น เรียกอีกอย่างว่าคลาสย่อยหรือคลาสที่ได้รับ
Polymorphism- นี่คือแนวคิดเชิงวัตถุที่สามารถใช้ฟังก์ชันเดียวกันเพื่อวัตถุประสงค์ที่แตกต่างกันได้ ตัวอย่างเช่นชื่อฟังก์ชันจะยังคงเหมือนเดิม แต่ใช้จำนวนอาร์กิวเมนต์ต่างกันและสามารถทำงานต่างกันได้
Overloading- ประเภทของความหลากหลายที่ตัวดำเนินการบางส่วนหรือทั้งหมดมีการใช้งานที่แตกต่างกันขึ้นอยู่กับประเภทของอาร์กิวเมนต์ ฟังก์ชั่นในทำนองเดียวกันสามารถทำงานหนักเกินไปได้ด้วยการใช้งานที่แตกต่าง
Data Abstraction - การแสดงข้อมูลใด ๆ ที่มีการซ่อนรายละเอียดการใช้งาน (บทคัดย่อ)
Encapsulation - หมายถึงแนวคิดที่เรารวมข้อมูลและฟังก์ชันสมาชิกทั้งหมดเข้าด้วยกันเพื่อสร้างวัตถุ
Constructor - หมายถึงฟังก์ชันชนิดพิเศษซึ่งจะถูกเรียกโดยอัตโนมัติเมื่อใดก็ตามที่มีการก่อตัวของวัตถุจากคลาส
Destructor - หมายถึงฟังก์ชันชนิดพิเศษซึ่งจะถูกเรียกโดยอัตโนมัติเมื่อใดก็ตามที่วัตถุถูกลบหรืออยู่นอกขอบเขต
การกำหนดคลาส PHP
รูปแบบทั่วไปสำหรับการกำหนดคลาสใหม่ใน PHP มีดังนี้ -
<?php
class phpClass {
var $var1;
var $var2 = "constant string";
function myfunc ($arg1, $arg2) {
[..]
}
[..]
}
?>
นี่คือคำอธิบายของแต่ละบรรทัด -
แบบฟอร์มพิเศษ classตามด้วยชื่อของคลาสที่คุณต้องการกำหนด
ชุดของวงเล็บปีกกาที่มีการประกาศตัวแปรและนิยามฟังก์ชันจำนวนเท่าใดก็ได้
การประกาศตัวแปรเริ่มต้นด้วยรูปแบบพิเศษ varซึ่งตามด้วยชื่อตัวแปร $ ธรรมดา พวกเขาอาจมีการกำหนดค่าเริ่มต้นให้กับค่าคงที่
คำจำกัดความของฟังก์ชันดูเหมือนฟังก์ชัน PHP แบบสแตนด์อโลน แต่เป็นฟังก์ชันเฉพาะของคลาสและจะใช้ในการตั้งค่าและเข้าถึงข้อมูลออบเจ็กต์
ตัวอย่าง
นี่คือตัวอย่างที่กำหนดประเภทหนังสือ -
<?php
class Books {
/* Member variables */
var $price;
var $title;
/* Member functions */
function setPrice($par){
$this->price = $par;
}
function getPrice(){
echo $this->price ."<br/>";
}
function setTitle($par){
$this->title = $par;
}
function getTitle(){
echo $this->title ." <br/>";
}
}
?>
ตัวแปร $thisเป็นตัวแปรพิเศษและหมายถึงวัตถุเดียวกันคือ ตัวเอง
การสร้างวัตถุใน PHP
เมื่อคุณกำหนดคลาสของคุณแล้วคุณสามารถสร้างวัตถุได้มากเท่าที่คุณต้องการสำหรับประเภทคลาสนั้น ต่อไปนี้เป็นตัวอย่างวิธีสร้างวัตถุโดยใช้new ตัวดำเนินการ
$physics = new Books;
$maths = new Books;
$chemistry = new Books;
ที่นี่เราได้สร้างวัตถุสามชิ้นขึ้นมาและวัตถุเหล่านี้ไม่ขึ้นต่อกันและจะมีการดำรงอยู่แยกกัน ต่อไปเราจะดูวิธีเข้าถึงฟังก์ชันสมาชิกและประมวลผลตัวแปรสมาชิก
เรียกใช้ฟังก์ชันสมาชิก
หลังจากสร้างวัตถุของคุณคุณจะสามารถเรียกใช้ฟังก์ชันสมาชิกที่เกี่ยวข้องกับวัตถุนั้นได้ ฟังก์ชันสมาชิกหนึ่งตัวจะสามารถประมวลผลตัวแปรสมาชิกของอ็อบเจ็กต์ที่เกี่ยวข้องเท่านั้น
ตัวอย่างต่อไปนี้แสดงวิธีการตั้งชื่อและราคาสำหรับหนังสือทั้งสามเล่มโดยเรียกใช้ฟังก์ชันสมาชิก
$physics->setTitle( "Physics for High School" );
$chemistry->setTitle( "Advanced Chemistry" );
$maths->setTitle( "Algebra" );
$physics->setPrice( 10 );
$chemistry->setPrice( 15 );
$maths->setPrice( 7 );
ตอนนี้คุณเรียกใช้ฟังก์ชันสมาชิกอื่นเพื่อรับค่าที่กำหนดในตัวอย่างด้านบน -
$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();
$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();
สิ่งนี้จะให้ผลลัพธ์ดังต่อไปนี้ -
Physics for High School
Advanced Chemistry
Algebra
10
15
7
ฟังก์ชั่นตัวสร้าง
Constructor Functions เป็นฟังก์ชันชนิดพิเศษที่เรียกโดยอัตโนมัติเมื่อใดก็ตามที่สร้างวัตถุ ดังนั้นเราจึงใช้ประโยชน์จากพฤติกรรมนี้อย่างเต็มที่โดยการเริ่มต้นหลาย ๆ สิ่งผ่านฟังก์ชันตัวสร้าง
PHP มีฟังก์ชันพิเศษที่เรียกว่า __construct()เพื่อกำหนดตัวสร้าง คุณสามารถส่งผ่านอาร์กิวเมนต์ได้มากเท่าที่คุณต้องการในฟังก์ชันตัวสร้าง
ตัวอย่างต่อไปนี้จะสร้างตัวสร้างหนึ่งรายการสำหรับคลาสหนังสือและจะเริ่มต้นราคาและชื่อหนังสือในเวลาที่สร้างวัตถุ
function __construct( $par1, $par2 ) {
$this->title = $par1;
$this->price = $par2;
}
ตอนนี้เราไม่จำเป็นต้องเรียกใช้ฟังก์ชัน set แยกกันเพื่อกำหนดราคาและชื่อเรื่อง เราสามารถเริ่มต้นตัวแปรสมาชิกทั้งสองนี้ได้ในเวลาที่สร้างออบเจ็กต์เท่านั้น ตรวจสอบตัวอย่างด้านล่าง -
$physics = new Books( "Physics for High School", 10 );
$maths = new Books ( "Advanced Chemistry", 15 );
$chemistry = new Books ("Algebra", 7 );
/* Get those set values */
$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();
$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();
สิ่งนี้จะให้ผลลัพธ์ดังต่อไปนี้ -
Physics for High School
Advanced Chemistry
Algebra
10
15
7
Destructor
เช่นเดียวกับฟังก์ชันตัวสร้างคุณสามารถกำหนดฟังก์ชันตัวทำลายโดยใช้ฟังก์ชัน __destruct(). คุณสามารถปลดปล่อยทรัพยากรทั้งหมดด้วยตัวทำลาย
มรดก
นิยามคลาส PHP สามารถเลือกที่จะสืบทอดจากนิยามคลาสพาเรนต์โดยใช้ส่วนขยาย ไวยากรณ์มีดังนี้ -
class Child extends Parent {
<definition body>
}
ผลของการสืบทอดคือคลาสย่อย (หรือคลาสย่อยหรือคลาสที่ได้รับ) มีลักษณะดังต่อไปนี้ -
มีการประกาศตัวแปรสมาชิกทั้งหมดของคลาสแม่โดยอัตโนมัติ
มีฟังก์ชันสมาชิกทั้งหมดโดยอัตโนมัติเหมือนกับพาเรนต์ซึ่ง (โดยค่าเริ่มต้น) จะทำงานในลักษณะเดียวกับที่ฟังก์ชันเหล่านั้นทำในพาเรนต์
ตัวอย่างต่อไปนี้สืบทอดคลาสหนังสือและเพิ่มฟังก์ชันเพิ่มเติมตามความต้องการ
class Novel extends Books {
var $publisher;
function setPublisher($par){
$this->publisher = $par;
}
function getPublisher(){
echo $this->publisher. "<br />";
}
}
ตอนนี้นอกเหนือจากฟังก์ชันที่สืบทอดแล้วคลาส Novel ยังมีฟังก์ชันสมาชิกเพิ่มเติมอีกสองฟังก์ชัน
การแทนที่ฟังก์ชัน
นิยามฟังก์ชันในคลาสย่อยจะแทนที่นิยามที่มีชื่อเดียวกันในคลาสพาเรนต์ ในคลาสลูกเราสามารถปรับเปลี่ยนนิยามของฟังก์ชันที่สืบทอดมาจากคลาสแม่
ในตัวอย่างต่อไปนี้ฟังก์ชัน getPrice และ getTitle จะถูกแทนที่เพื่อส่งคืนค่าบางค่า
function getPrice() {
echo $this->price . "<br/>";
return $this->price;
}
function getTitle(){
echo $this->title . "<br/>";
return $this->title;
}
สมาชิกสาธารณะ
เว้นแต่คุณจะระบุเป็นอย่างอื่นคุณสมบัติและวิธีการของคลาสจะเป็นแบบสาธารณะ กล่าวคืออาจเข้าถึงได้ในสามสถานการณ์ที่เป็นไปได้ -
จากนอกชั้นเรียนที่มีการประกาศ
จากภายในคลาสที่มีการประกาศ
จากภายในคลาสอื่นที่ใช้คลาสที่มีการประกาศ
จนถึงตอนนี้เราได้เห็นสมาชิกทั้งหมดเป็นสมาชิกสาธารณะ หากคุณต้องการ จำกัด การเข้าถึงของสมาชิกในชั้นเรียนให้คุณกำหนดสมาชิกชั้นเรียนเป็นprivate หรือ protected.
สมาชิกส่วนตัว
โดยการกำหนดสมาชิกเป็นส่วนตัวคุณจะ จำกัด การเข้าถึงเฉพาะคลาสที่มีการประกาศ ไม่สามารถอ้างถึงสมาชิกส่วนตัวจากคลาสที่สืบทอดคลาสที่ประกาศไว้และไม่สามารถเข้าถึงได้จากภายนอกคลาส
สมาชิกชั้นเรียนสามารถทำให้เป็นส่วนตัวได้โดยใช้ private คีย์เวิร์ดหน้าสมาชิก
class MyClass {
private $car = "skoda";
$driver = "SRK";
function __construct($par) {
// Statements here run every time
// an instance of the class
// is created.
}
function myPublicFunction() {
return("I'm visible!");
}
private function myPrivateFunction() {
return("I'm not visible outside!");
}
}
เมื่อคลาสMyClassได้รับการสืบทอดโดยคลาสอื่นโดยใช้การขยาย myPublicFunction () จะมองเห็นได้เช่นเดียวกับไดรเวอร์ $ คลาสที่ขยายออกไปจะไม่มีการรับรู้หรือเข้าถึง myPrivateFunction และ $ car เนื่องจากถูกประกาศว่าเป็นส่วนตัว
สมาชิกที่ได้รับการคุ้มครอง
คุณสมบัติหรือเมธอดที่ได้รับการป้องกันสามารถเข้าถึงได้ในคลาสที่มีการประกาศเช่นเดียวกับในคลาสที่ขยายคลาสนั้น สมาชิกที่ได้รับการคุ้มครองจะไม่สามารถใช้ได้นอกคลาสทั้งสองประเภทนี้ สมาชิกชั้นเรียนสามารถป้องกันได้โดยใช้protected คีย์เวิร์ดต่อหน้าสมาชิก
นี่คือ MyClass เวอร์ชันอื่น -
class MyClass {
protected $car = "skoda";
$driver = "SRK";
function __construct($par) {
// Statements here run every time
// an instance of the class
// is created.
}
function myPublicFunction() {
return("I'm visible!");
}
protected function myPrivateFunction() {
return("I'm visible in child class!");
}
}
อินเทอร์เฟซ
อินเทอร์เฟซถูกกำหนดเพื่อให้ชื่อฟังก์ชันทั่วไปแก่ผู้ใช้งาน ผู้ใช้ที่แตกต่างกันสามารถใช้อินเทอร์เฟซเหล่านั้นได้ตามความต้องการ คุณสามารถพูดได้ว่าอินเทอร์เฟซคือโครงกระดูกที่นักพัฒนาใช้งาน
ใน PHP5 เป็นไปได้ที่จะกำหนดอินเทอร์เฟซเช่นนี้ -
interface Mail {
public function sendMail();
}
จากนั้นหากคลาสอื่นใช้อินเทอร์เฟซนั้นเช่นนี้ -
class Report implements Mail {
// sendMail() Definition goes here
}
ค่าคงที่
ค่าคงที่ค่อนข้างเหมือนตัวแปรโดยที่มันเก็บค่าไว้ แต่จริงๆแล้วเหมือนฟังก์ชันมากกว่าเพราะค่าคงที่ไม่เปลี่ยนรูป เมื่อคุณประกาศค่าคงที่แล้วจะไม่มีการเปลี่ยนแปลง
การประกาศค่าคงที่หนึ่งค่านั้นทำได้ง่ายเช่นเดียวกับที่ทำใน MyClass เวอร์ชันนี้ -
class MyClass {
const requiredMargin = 1.7;
function __construct($incomingValue) {
// Statements here run every time
// an instance of the class
// is created.
}
}
ในคลาสนี้ requiredMargin เป็นค่าคงที่ มีการประกาศด้วยคีย์เวิร์ด const และไม่สามารถเปลี่ยนแปลงเป็นอย่างอื่นได้นอกจาก 1.7 โปรดสังเกตว่าชื่อค่าคงที่ไม่มี $ นำหน้าเหมือนชื่อตัวแปร
คลาสนามธรรม
คลาสนามธรรมคือคลาสที่ไม่สามารถสร้างอินสแตนซ์ได้ แต่สืบทอดมาเท่านั้น คุณประกาศคลาสนามธรรมด้วยคีย์เวิร์ดabstractเช่นนี้ -
เมื่อรับช่วงจากคลาสนามธรรมเด็กต้องกำหนดวิธีการทั้งหมดที่ทำเครื่องหมายนามธรรมไว้ในการประกาศคลาสของผู้ปกครอง นอกจากนี้ต้องกำหนดวิธีการเหล่านี้ด้วยการมองเห็นเดียวกัน
abstract class MyAbstractClass {
abstract function myAbstractFunction() {
}
}
โปรดทราบว่าคำจำกัดความของฟังก์ชันภายในคลาสนามธรรมต้องนำหน้าด้วยคำสำคัญนามธรรม ไม่ถูกกฎหมายที่จะมีนิยามฟังก์ชันนามธรรมภายในคลาสที่ไม่ใช่นามธรรม
คำหลักคงที่
การประกาศสมาชิกคลาสหรือเมธอดเป็นแบบคงที่ทำให้สามารถเข้าถึงได้โดยไม่จำเป็นต้องมีการสร้างอินสแตนซ์ของคลาส สมาชิกที่ประกาศว่าเป็นสแตติกไม่สามารถเข้าถึงได้ด้วยอ็อบเจ็กต์คลาสที่สร้างอินสแตนซ์ (แม้ว่าวิธีการคงที่สามารถทำได้)
ลองใช้ตัวอย่างต่อไปนี้ -
<?php
class Foo {
public static $my_static = 'foo';
public function staticValue() {
return self::$my_static;
}
}
print Foo::$my_static . "\n";
$foo = new Foo();
print $foo->staticValue() . "\n";
?>
คำหลักสุดท้าย
PHP 5 แนะนำคีย์เวิร์ดสุดท้ายซึ่งป้องกันไม่ให้คลาสย่อยแทนที่เมธอดโดยนำหน้านิยามด้วย final หากคลาสถูกกำหนดขั้นสุดท้ายจะไม่สามารถขยายได้
ตัวอย่างต่อไปนี้ส่งผลให้เกิดข้อผิดพลาดร้ายแรง: ไม่สามารถแทนที่วิธีสุดท้าย BaseClass :: moreTesting ()
<?php
class BaseClass {
public function test() {
echo "BaseClass::test() called<br>";
}
final public function moreTesting() {
echo "BaseClass::moreTesting() called<br>";
}
}
class ChildClass extends BaseClass {
public function moreTesting() {
echo "ChildClass::moreTesting() called<br>";
}
}
?>
เรียกผู้สร้างหลัก
แทนที่จะเขียนคอนสตรัคเตอร์ใหม่ทั้งหมดสำหรับคลาสย่อยให้เขียนโดยเรียกคอนสตรัคเตอร์ของพาเรนต์อย่างชัดเจนจากนั้นทำสิ่งที่จำเป็นเพิ่มเติมเพื่อสร้างอินสแตนซ์ของคลาสย่อย นี่คือตัวอย่างง่ายๆ -
class Name {
var $_firstName;
var $_lastName;
function Name($first_name, $last_name) {
$this->_firstName = $first_name;
$this->_lastName = $last_name;
}
function toString() {
return($this->_lastName .", " .$this->_firstName);
}
}
class NameSub1 extends Name {
var $_middleInitial;
function NameSub1($first_name, $middle_initial, $last_name) {
Name::Name($first_name, $last_name);
$this->_middleInitial = $middle_initial;
}
function toString() {
return(Name::toString() . " " . $this->_middleInitial);
}
}
ในตัวอย่างนี้เรามีคลาสพาเรนต์ (Name) ซึ่งมีคอนสตรัคเตอร์สองอาร์กิวเมนต์และคลาสย่อย (NameSub1) ซึ่งมีคอนสตรัคเตอร์สามอาร์กิวเมนต์ คอนสตรัคเตอร์ของฟังก์ชัน NameSub1 โดยการเรียกคอนสตรัคเตอร์พาเรนต์อย่างชัดเจนโดยใช้ :: syntax (ส่งผ่านอาร์กิวเมนต์สองตัวไปพร้อมกัน) จากนั้นตั้งค่าฟิลด์เพิ่มเติม ในทำนองเดียวกัน NameSub1 กำหนดฟังก์ชัน non constructor toString () ในรูปแบบของฟังก์ชันพาเรนต์ที่แทนที่
NOTE- ตัวสร้างสามารถกำหนดด้วยชื่อเดียวกับชื่อของคลาส ถูกกำหนดไว้ในตัวอย่างข้างต้น