Php 简明教程
PHP – Traits
在 PHP 中,一个类只能从一个父类继承,多重继承在 PHP 中没有定义。PHP 中的 Traits 被引入来克服此限制。你可以在一个 Trait 中定义一个或多个方法,它们可以自由地重复用于各种独立的类。
In PHP, a class can inherit only from one parent class, multiple inheritance is not defined in PHP. Traits in PHP have been introduced to overcome this limitation. You can define one or more method in a trait, which can be reused freely in various independent classes.
Syntax
"trait" 关键字按以下语法使用 −
The "trait" keyword is used as per the following syntax −
trait mytrait {
function method1() {
/*function body*/
}
function method2() {
/*function body*/
}
}
为了能够调用 Trait 中的方法,需要使用 use 关键字将其提供给另一个类。
To be able to call the methods in a trait, it needs to made available to another class with use keyword.
Example
Trait 类似于一个类,但只用于以细粒度和一致的方式对功能进行分组。无法单独实例化 Trait。
A Trait is similar to a class, but only intended to group functionality in a fine-grained and consistent way. It is not possible to instantiate a Trait on its own.
<?php
trait mytrait {
public function hello() {
echo "Hello World from " . __TRAIT__ . "";
}
}
class myclass {
use mytrait;
}
$obj = new myclass();
$obj->hello();
?>
它将生成以下 output −
It will produce the following output −
Hello World from mytrait
Example
一个 Trait 可以用在多个类中。以下示例有一个带有 avg() 函数 int 的 mytrait。它在 marks 类中使用。percent() 方法在内部从 Trait 调用 avg() 函数。
A trait can be used in more than one classes. The following example has a mytrait with avg() function int it. It is used inside a marks class. The percent() method internally calls the avg() function from the trait.
请看以下示例:
Take a look at the following example −
<?php
trait mytrait {
function avg($x, $y) {
return ($x+$y)/2;
}
}
class marks {
use mytrait;
private int $m1, $m2;
function __construct($x, $y) {
$this->m1 = $x;
$this->m2 = $y;
}
function percent():float {
return $this->avg($this->m1, $this->m2);
}
}
$obj = new marks(50, 60);
echo "percentage: " . $obj->percent();
?>
它将生成以下 output −
It will produce the following output −
percentage: 55
Using Multiple Traits
一个类可以使用多个 Trait。这里我们有两个 Trait,每个 Trait 都带有一个函数,分别对两个数字进行加法和乘法。两者都在第三个类中使用。
A class can use more than one traits. Here we have two traits with one function each performing addition and multiplication of two numbers. Both are used inside a third class.
<?php
trait addition {
function add($x, $y) {
return $x+$y;
}
}
trait multiplication {
function multiply($x, $y) {
return $x*$y;
}
}
class numbers {
use addition, multiplication;
private int $m1, $m2;
function __construct($x, $y) {
$this->m1 = $x;
$this->m2 = $y;
}
function calculate():array {
$arr = [$this->add($this->m1, $this->m2), $this->multiply($this->m1, $this->m2)];
return $arr;
}
}
$obj = new numbers(50, 60);
$res = $obj->calculate();
echo "Addition: " . $res[0] . PHP_EOL;
echo "Multiplication: " . $res[1] . PHP_EOL;
?>
它将生成以下 output −
It will produce the following output −
Addition: 110
Multiplication: 3000
Overriding Trait Function
当一个类使用某个 Trait 时,其函数对它可用,就像子类继承父类方法一样。Trait 函数也可以被覆盖。
When a class uses a certain trait, its function are available to it just as a child class inherits the parent methods. The trait function may also be overridden.
<?php
trait mytrait {
public function sayHello() {
echo 'Hello World!';
}
}
class myclass {
use mytrait;
public function sayHello() {
echo 'Hello PHP!';
}
}
$o = new myclass();
$o->sayHello();
?>
它将生成以下 output −
It will produce the following output −
Hello PHP!
The "insteadof" Keyword
有时,两个以上的 Trait 可能会具有相同名称的函数。因此,在类中使用它们会导致模棱两可的情况。PHP 提供 insteadof 关键字来告知解析器你要使用哪个 Trait 函数。
Sometimes, more two traits might have same name of the function. Hence, using them in a class creates ambiguous situation. PHP provides insteadof keyword to tell the parser function from which trait you intend to use.
<?php
trait mytrait {
public function sayHello() {
echo 'Hello World!';
}
}
trait newtrait {
public function sayHello() {
echo 'Hello PHP!';
}
}
class myclass {
use mytrait, newtrait{
newtrait::sayHello insteadof mytrait;
}
}
$o = new myclass();
$o->sayHello();
?>
它将生成以下 output −
It will produce the following output −
Hello PHP!
Aliasing a Trait Function
如果你希望能够从这两个 Trait 中调用函数,即使它们具有同名的函数,解决方法是为其中一个指定别名。
If you want to be able to call functions from both traits even if they have function with same name, a workaround is to specify an alias name to one of them.
Example
在以下示例中,我们将 mytrait 中的 sayHello() 称为 hello() −
In the following example, we will call sayHello() from mytrait as hello() −
<?php
trait mytrait {
public function sayHello() {
echo 'Hello World!' . PHP_EOL;
}
}
trait newtrait {
public function sayHello() {
echo 'Hello PHP!' . PHP_EOL;
}
}
class myclass {
use mytrait, newtrait{
mytrait::sayHello as hello;
newtrait::sayHello insteadof mytrait;
}
}
$o = new myclass();
$o->hello();
$o->sayHello();
?>
它将生成以下 output −
It will produce the following output −
Hello World!
Hello PHP!