PHP之认识(一)关于Traits的用法详解

PHP是单继承的语言,在PHP 5.4 Traits出现之前,PHP的类无法同时从两个基类继承属性或方法。Traits的出现解决了这一问题。

1、通过在类中使用use关键字声明要组合的Trait名称,而具体某个Trait的声明使用trait关键词,Trait不能直接实例化。具体用法:


<?php
trait Person{
	public $name="person";
	public function talk(){
		echo "我是{$this->name}<br/>";
	}
}
class Teacher{
	public function speak(){
		echo "我能教书<br/>";
	}
}
class Student extends Teacher{
	use Person;
	public function study(){
		echo "我需要学习<br/>";
	}
}
$student = new Student();
$student->talk();
$student->speak();
$student->study();
?>

2、Trait、父类和本类中都存在某个同名的属性或者方法是,会保留哪一个?

<?php
trait Person{
	public $name="person";
	public function talk(){
		echo "我是{$this->name}<br/>";
	}
	 public function hello() {
        echo "hello Person<br/>";
    }
}
class Teacher{
	public function talk(){
		echo "我能教书<br/>";
	}
	 public function hello() {
        echo "hello Teacher<br/>";
    }
}
class Student extends Teacher{
	use Person;
	public function talk(){
		echo "我需要学习<br/>";
	}
}
$student = new Student();
$student->talk();
$student->hello();
?>

结果输出

我需要学习
hello Person

由结果可知

//trait的方法覆盖了基类Person中的方法,所以Person中的方法hello和speak被覆盖
//当方法或属性同名时,当前类中的方法会覆盖 trait的方法,所以此处talk会覆盖trait中的talk

3、如果多个Trait中包含同名方法或者属性时,会怎样呢?答案是当组合的多个Trait包含同名属性或者方法时,需要明确声明解决冲突,否则会产生一个致命错误。使用insteadof和as操作符来解决冲突,insteadof是使用某个方法替代另一个,而as是给方法取一个别名,具体用法请看代码:

<?php
trait Person1{
	public function sayHello(){
		echo "Hello Person1<br/>";
	}
	public function hi(){
		echo "Hi Person1<br/>";
	}
}
trait Person2{
		public function sayHello(){
			echo "Hello Person2<br/>";
		}
		public function hi(){
			echo "Hi Person2<br/>";
		}
}
class Class1{
	use Person1,Person2{
		Person1::sayHello insteadof Person2;
		Person2::hi insteadof Person1;
	}
}
class Class2{
	use Person1,Person2{
		Person1::sayHello insteadof Person2;
		Person2::hi insteadof Person1;
		Person1::sayHello as he;		//在这里as只是起到别名的作用,如果去掉
		Person2::hi as she;				//insteadof语句会造成错误
	}
}
$obj1 = new Class1();
$obj1->sayHello();
$obj1->hi();
echo "<br/>";
$obj2 = new Class2();
$obj2->sayHello();
$obj2->hi();
$obj2->he();
$obj2->she();
?>

结果:

Hello Person1
Hi Person2

Hello Person1
Hi Person2
Hello Person1
Hi Person2

as关键词还有另外一个用途,那就是修改方法的访问控制:

<?php
trait Person{
	function sayHello(){
		echo "Hello<br/>";
	}
}
class Class1{
	use Person{
		sayHello as protected;
	}
}
class Class2{
	use Person{
		Person::sayHello as private hi;
	}
}
$obj1 = new Class1();
$obj1->sayHello();
echo "<br/>";
$obj2 = new Class2();
$obj2->sayHello();		//当注释掉$obj1时可见Hello
$obj2->hi();
?>

Trait 也能组合Trait,Trait中支持抽象方法、静态属性及静态方法,测试代码如下:

<?php
trait Hello{
	function sayHello(){
		echo "Hello ";
	}
}
trait World{
	use Hello;
	function sayWorld(){
		echo "world!<br/>";
	}
}
class Class1{
	use World;				//连续继承
	function sayHelloWorld(){
		echo "Hello world!<br/>";
	}
}
$obj1 = new Class1();
$obj1->sayHello();
$obj1->sayWorld();
$obj1->sayHelloWorld();
?>

结果:

Hello world!
Hello world!

转载:https://www.cnblogs.com/phpper/p/8978098.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值