PHP OOP - คลาสนามธรรม
PHP - คลาสนามธรรมและวิธีการคืออะไร?
คลาสนามธรรมและวิธีการคือเมื่อคลาสพาเรนต์มีเมธอดที่มีชื่อ แต่ต้องการคลาสลูกเพื่อกรอกงาน
คลาสนามธรรมคือคลาสที่มีเมธอดนามธรรมอย่างน้อยหนึ่งวิธี วิธีนามธรรมคือวิธีการที่มีการประกาศ แต่ไม่ได้นำไปใช้ในโค้ด
คลาสนามธรรมหรือเมธอดถูกกำหนดด้วยabstract
คีย์เวิร์ด:
ไวยากรณ์
<?php
abstract class
ParentClass {
abstract public function someMethod1();
abstract public function someMethod2($name, $color);
abstract
public function someMethod3() : string;
}
?>
เมื่อสืบทอดจากคลาสนามธรรม เมธอดคลาสลูกต้องถูกกำหนดด้วยชื่อเดียวกัน และตัวแก้ไขการเข้าถึงแบบเดียวกันหรือแบบจำกัดน้อยกว่า ดังนั้น ถ้าเมธอดนามธรรมถูกกำหนดเป็นป้องกัน เมธอดคลาสลูกต้องถูกกำหนดเป็นป้องกันหรือสาธารณะ แต่ไม่เป็นแบบส่วนตัว นอกจากนี้ ประเภทและจำนวนของอาร์กิวเมนต์ที่ต้องการจะต้องเหมือนกัน อย่างไรก็ตาม คลาสย่อยอาจมีอาร์กิวเมนต์ที่เป็นทางเลือกเพิ่มเติม
ดังนั้น เมื่อคลาสลูกสืบทอดมาจากคลาสนามธรรม เรามีกฎดังต่อไปนี้:
- ต้องกำหนดวิธีการคลาสลูกด้วยชื่อเดียวกันและจะประกาศวิธีการนามธรรมหลัก
- ต้องกำหนดวิธีการคลาสลูกด้วยตัวแก้ไขการเข้าถึงที่ จำกัด เดียวกันหรือน้อยกว่า
- จำนวนอาร์กิวเมนต์ที่ต้องการต้องเท่ากัน อย่างไรก็ตาม คลาสลูกอาจมีอาร์กิวเมนต์เสริมเพิ่มเติม
ลองดูตัวอย่าง:
ตัวอย่าง
<?php
// Parent class
abstract class Car {
public
$name;
public
function __construct($name) {
$this->name = $name;
}
abstract public function intro() : string;
}
// Child classes
class
Audi extends Car {
public
function intro() : string {
return "Choose German
quality! I'm an $this->name!";
}
}
class
Volvo extends Car {
public
function intro() : string {
return "Proud to be
Swedish! I'm a $this->name!";
}
}
class
Citroen extends Car {
public
function intro() : string {
return "French
extravagance! I'm a $this->name!";
}
}
// Create objects from the child classes
$audi = new
audi("Audi");
echo $audi->intro();
echo "<br>";
$volvo = new
volvo("Volvo");
echo $volvo->intro();
echo "<br>";
$citroen = new citroen("Citroen");
echo $citroen->intro();
?>
ตัวอย่างที่อธิบาย
คลาส Audi, Volvo และ Citroen สืบทอดมาจากคลาสรถยนต์ ซึ่งหมายความว่าคลาส Audi, Volvo และ Citroen สามารถใช้คุณสมบัติ $name สาธารณะรวมถึงเมธอด __construct() สาธารณะจากคลาส Car เนื่องจากการสืบทอด
แต่ intro() เป็นวิธีนามธรรมที่ควรกำหนดในคลาสย่อยทั้งหมดและควรส่งคืนสตริง
PHP - ตัวอย่างคลาสนามธรรมเพิ่มเติม
ลองดูตัวอย่างอื่นที่วิธีนามธรรมมีข้อโต้แย้ง:
ตัวอย่าง
<?php
abstract class ParentClass {
// Abstract method
with an argument
abstract protected
function prefixName($name);
}
class ChildClass extends ParentClass {
public function prefixName($name) {
if ($name == "John Doe") {
$prefix = "Mr.";
} elseif ($name == "Jane Doe") {
$prefix =
"Mrs.";
} else {
$prefix = "";
}
return
"{$prefix} {$name}";
}
}
$class = new ChildClass;
echo $class->prefixName("John
Doe");
echo "<br>";
echo $class->prefixName("Jane Doe");
?>
ลองดูตัวอย่างอื่นที่เมธอด abstract มีอาร์กิวเมนต์ และคลาสย่อยมีอาร์กิวเมนต์ทางเลือกสองอาร์กิวเมนต์ที่ไม่ได้กำหนดไว้ในเมธอด abstract ของพาเรนต์:
ตัวอย่าง
<?php
abstract class ParentClass {
// Abstract method
with an argument
abstract protected
function prefixName($name);
}
class ChildClass extends ParentClass {
// The child class may define optional arguments that are not in the parent's
abstract method
public function prefixName($name, $separator = ".",
$greet = "Dear") {
if ($name == "John Doe") {
$prefix = "Mr";
} elseif ($name == "Jane Doe") {
$prefix =
"Mrs";
} else {
$prefix = "";
}
return
"{$greet} {$prefix}{$separator} {$name}";
}
}
$class = new ChildClass;
echo $class->prefixName("John
Doe");
echo "<br>";
echo $class->prefixName("Jane Doe");
?>