17-3细说trait与继承-–PHP实战开发教程

17-3细说trait与继承-–PHP实战开发教程

没呐混靡簿奉葱仆奢叹段究琉


php中只允许单继承,不允许如下所示的多继承:

<?php
class A extends B,C
{
    
}

Trait是什么?
1.trait是为单继承语言量身定制的代码复用机制;
2.之前可以通过函数或类来实现代码复用;
3.trait可以简单的理解为一个类方法的集合,工作在父类与子类之间;
4.但是trait不仅仅局限于方法集合,还支持抽象,静态与属性;
5.当前类成员会覆盖trait类成员,而trait中的成员,又可以覆盖同名类成员
6.重要提示:trait不是类,不能实例化,切记切记


新建demo3.php

<?php

if(!class_exists('Person'))
{
    class Person
    {
        private  $name;
        public function __construct($name="小明")
        {
            $this->name=$name;
        }
        public function study($course="php")
        {
            return $this->name."在学习".$course;
        }
    }
}

//trait 可以看做是一个特殊的类,但不能被实例化,仅允许被类调用
if(!trait_exists('Course'))
{
    trait Course
    {
        //trait中允许有属性
        public $friend="小华";

        public function sport($name="踢足球")
        {
            //trait可以访问父类中的属性
            return $this->name.'和'.$this->friend.'在'.$name;;
        }

        //可以声明抽象静态方法
        abstract public static function hobby($name);

        //与Person类同名的方法
        public function study($course)
        {
            return $this->name.'在学习'.$course;
        }
    }
}

//Student类有了一个父类,还有一个trait类
class Student extends Person
{


}

//实例化Student
$student=new Student();
echo $student->study();

执行,警告是因为没有对抽象方法hobby()进行实现,先不用管

17-3细说trait与继承-–PHP实战开发教程第1张


trait可以认为是父类与子类之间的中间层

17-3细说trait与继承-–PHP实战开发教程第2张

trait是一个特殊的类,trait可以对子类调用父类的方法进行拦截,当父类和trait有同名的方法,子类调用该方法时,trait会拦截,让子类调用trait的同名方法

17-3细说trait与继承-–PHP实战开发教程第3张

trait是方法集,子类除了可以从父类中继承属性方法之外,还可以从trait中继承属性和方法,实现多继承

17-3细说trait与继承-–PHP实战开发教程第4张


trait作为父类和子类的中间层,会拦截父类中的同名方法

<?php

if(!class_exists('Person'))
{
    class Person
    {
        protected  $name;
        public function __construct($name="小明")
        {
            $this->name=$name;
        }
        public function study($course="php")
        {
            return $this->name."在学习".$course;
        }
    }
}

//trait 可以看做是一个特殊的类,但不能被实例化,仅允许被类调用
if(!trait_exists('Course'))
{
    trait Course
    {
        //trait中允许有属性
        public $friend="小华";

        public function sport($name="踢足球")
        {
            //trait可以访问父类中的属性
            return $this->name.'和'.$this->friend.'在'.$name;;
        }

        //可以声明抽象静态方法
        abstract public static function hobby($name);

        //与Person类同名的方法
        public function study($course="java")
        {
            return $this->friend.'在学习'.$course;
        }
    }
}

//Student类有了一个父类,还有一个trait类
class Student extends Person
{
    //导入trait类
    use Course;

    //必须对trait中的抽象方法进行实现
    public static function hobby($name)
    {
        return $name;
    }

}

//实例化Student
$student=new Student();
echo $student->study();

执行,调用的是trait中的study()方法

17-3细说trait与继承-–PHP实战开发教程第5张

注意:父类的属性被继承,声明方式只能是protected或者public


子类中也有study()函数时

<?php

if(!class_exists('Person'))
{
    class Person
    {
        protected  $name;
        public function __construct($name="小明")
        {
            $this->name=$name;
        }
        public function study($course="php")
        {
            return $this->name."在学习".$course;
        }
    }
}

//trait 可以看做是一个特殊的类,但不能被实例化,仅允许被类调用
if(!trait_exists('Course'))
{
    trait Course
    {
        //trait中允许有属性
        public $friend="小华";

        public function sport($name="踢足球")
        {
            //trait可以访问父类中的属性
            return $this->name.'和'.$this->friend.'在'.$name;;
        }

        //可以声明抽象静态方法
        abstract public static function hobby($name);

        //与Person类同名的方法
        public function study($course="java")
        {
            return $this->friend.'在学习'.$course;
        }
    }
}

//Student类有了一个父类,还有一个trait类
class Student extends Person
{

    //导入trait类
    use Course;

    protected $name="小军";
    //必须对trait中的抽象方法进行实现
    public static function hobby($name)
    {
        return $name;
    }

    public function study($course="python")
    {
        return $this->name."在学习".$course;
    }

}

//实例化Student
$student=new Student();
echo $student->study();

执行,此时调用的是子类Student中的study()方法,如果需要使用子类的属性,即输出:小军在学习python,则需要在Student中写构造方法

17-3细说trait与继承-–PHP实战开发教程第6张

方法优先级顺序:子类>trait>父类


禽苦镀饰括怪洪毙蓝讥脯通凯