แนะนำตัว
PHP ไม่รองรับการสืบทอดหลายรายการ ข้อจำกัดนี้เอาชนะได้ด้วยคุณลักษณะของลักษณะ . เป็นกลไกของการใช้รหัสซ้ำ คำจำกัดความของลักษณะคล้ายกับคลาส อย่างไรก็ตาม ไม่สามารถสร้างอินสแตนซ์ได้โดยตรง แทนที่จะใช้ฟังก์ชันของคุณลักษณะในชั้นเรียนโดย ใช้ คำสำคัญ. ดังนั้นคลาสสามารถใช้เมธอดที่กำหนดไว้ในลักษณะหรือสามารถแทนที่ได้ นี่เป็นนอกเหนือจากคลาสหลักอื่น ๆ ที่อาจสืบทอดมา
ลักษณะยังคล้ายกับอินเทอร์เฟซ ความแตกต่างคืออินเทอร์เฟซไม่ได้ให้คำจำกัดความของเมธอดภายใน ซึ่งต้องทำโดยใช้คลาส อย่างไรก็ตาม วิธีการของ Trait จะให้คำจำกัดความ ซึ่งอาจจะหรืออาจจะไม่ถูกแทนที่โดยคลาสที่ใช้คุณลักษณะนี้
ไวยากรณ์
<?php
trait testtrait{
public function test1(){
//body of method
}
}
//using trait
class testclass{
use testtrait
//rest of members in class
}
?> ตัวอย่าง
ในโค้ดต่อไปนี้ คุณลักษณะที่มีสองวิธีถูกใช้ในคลาสที่แทนที่หนึ่งในเมธอด
ตัวอย่าง
<?php
//definition of trait
trait testtrait{
public function test1(){
echo "test1 method in trait\n";
}
public function test2(){
echo "test2 method in trait\n";
}
}
//using trait
class testclass{
use testtrait;
public function test1(){
echo "test1 method overridden\n";
}
}
$obj=new testclass();
$obj->test1();
$obj->test2();
?> ผลลัพธ์
ผลลัพธ์จะเป็นดังนี้ −
test1 method overridden test2 method in trait
อุปนิสัยในคลาสเด็ก
นี่คือข้อได้เปรียบหลักของลักษณะ คลาสที่มีพาเรนต์ยังสามารถใช้ trait และอาจเลือกที่จะแทนที่เมธอดของมัน จึงได้รับมรดกหลายอย่างอย่างมีประสิทธิภาพ ตัวอย่างของคุณลักษณะนี้ได้รับด้านล่าง −
ตัวอย่าง
<?php
//definition of trait
trait testtrait{
public function test1(){
echo "test1 method in trait\n";
}
}
//parent class
class parentclass{
public function test2(){
echo "test2 method in parent\n";
}
}
//using trait and parent class
class childclass extends parentclass{
use testtrait;
public function test1(){
echo "parent method overridden\n";
}
public function test2(){
echo "trait method overridden\n";
}
}
$obj=new childclass();
$obj->test1();
$obj->test2();
?> ผลลัพธ์
รหัสด้านบนสร้างผลลัพธ์ดังต่อไปนี้ -
parent method overridden trait method overridden
ลักษณะพร้อมอินเทอร์เฟซ
เป็นไปได้ที่จะมีคลาสที่ใช้อินเตอร์เฟส ขยายคลาสพาเรนต์อื่น ๆ และใช้ trait พร้อมกัน
ตัวอย่าง
<?php
//definition of trait
trait mytrait{
public function test1(){
echo "test1 method in trait1\n";
}
}
class myclass{
public function test2(){
echo "test2 method in parent class\n";
}
}
interface myinterface{
public function test3();
}
//using trait and parent class
class testclass extends myclass implements myinterface{
use mytrait;
public function test3(){
echo "implementation of test3 method\n";
}
}
$obj=new testclass();
$obj->test1();
$obj->test2();
$obj->test3();
?> ผลลัพธ์
สิ่งนี้จะสร้างผลลัพธ์ต่อไปนี้ -
test1 method in trait1 test2 method in parent class implementation of test3 method
การแก้ไขข้อขัดแย้ง
ถ้าคลาสใช้สองลักษณะที่มีเมธอดร่วมกัน ข้อขัดแย้งจะได้รับการแก้ไขโดยตัวดำเนินการแก้ไขขอบเขตและแทน คีย์เวิร์ด
ตัวอย่าง
<?php
trait trait1{
public function test1(){
echo "test1 method in trait1\n";
}
public function test2(){
echo "test2 method in trait1\n";
}
}
trait trait2{
public function test1(){
echo "test1 method in trait2\n";
}
public function test2(){
echo "test2 method in trait2\n";
}
}
//using trait and parent class
class testclass {
use trait1, trait2{
trait1::test1 insteadof trait2;
trait2::test2 insteadof trait1;
}
}
$obj=new testclass();
$obj->test1();
$obj->test2();
?> ผลลัพธ์
สคริปต์ด้านบนสร้างผลลัพธ์ต่อไปนี้
test1 method in trait1 test2 method in trait2