匿名类

目录:

  • 基本语法

  • 匿名类的继承

    • 匿名类继承普通类

    • 匿名类继承接口

  • 匿名嵌套在一个类中

基本语法:

匿名类的声明与使用是同时进行的,它具备其他类所具备的所有功能,差别在与匿名类没有类名。匿名类的一次性小任务代码流程对性能提升帮助很大,你不必将整个类都写完再使用它。

虽然我们看到的匿名类是没有命名的,但在PHP内部,会在内存的引用地址表中为其分配一个全局唯一的名称。例如全局的一个匿名类的名称为 class@0x5e4f2d5s132

匿名类的语法与命名类的语法相似,仅仅是没有设置类名,语法如下:

new class(argument) { defintion };

通俗易懂的例子:

<?php
$name = new class {
    public function __construct()
    {
        echo 'hello world';
    }
};

结果仅显示一行 hello world

参数可以直接设置在匿名类中当做构造函数的参数,如下代码:

<?php
$name = new class('hello world') {
    public function __construct(string $name)
    {
        echo $name;
    }
};

匿名类的继承:

  • 匿名类继承普通类

  • 匿名类继承接口

匿名类继承普通类

匿名类在继承方面与命名类相同,一样可以继承父类及父类的方法,如下代码:

<?php
//构造函数的参数。

class User
{
    protected $number;

    public function __construct()
    {
        echo "I am parent class constructor";
    }

    public function getNumber() : float
    {
        return $this->num;
    }
}

//匿名类继承Info类

$number = new class(5) extends User
{
    public function __construct(float $num)
    {
        parent::__construct();
        $this->num = $num;
    }
};

echo $number->getNumber();

输出结果:

I am parent class constructor5

通过使用匿名类继承了父类User。同时,父类的public,protected,private属性在匿名类中依然有效。

匿名类继承接口

匿名类同样可以继承接口,方式与继承普通命名类相同。

<?php
interface Info
{
    public function __construct(string $name, string $address);
    public function getName() : string;
    public function getAddress() : string;
}

// 修改后的User类
class User
{
    protected $number;

    protected $name;

    protected $address;

    public function __construct()
    {
        echo "I am parent class constructor";
    }

    public function getNumber() : float
    {
        return $this->num;
    }
}

    $info = new class('revin', 'China') extends User implements Info
    {
        public function __construct(string $name, string $address)
        {
            $this->name    = $name;
            $this->address = $address;
        }

        public function getName() : string
        {
            return $this->name;
        }

        public function getAddress() : string
        {
            return $this->address;
        }
    };

echo $info->getName() . ' ' . $info->getAddress();

输出结果:

revin China

匿名嵌套在一个类中

匿名类可以嵌套在一个类中使用。

class Math
{
    public $first_number = 10;

    public $second_number = 20;


    protected function add() : float
    {
        return $this->first_number + $this->second_number;
    }

    public function multiply_sum()
    {
        return new class() extends Math
        {

            public function multiply($third_number) : float
            {
                return $this->add() * $third_number;
            }
        };
    }
}

$math = new Math();

echo $math->multiply_sum()->multiply(2);

输出结果

60

实现过程:

  1. Math类中有一个multiply_sum方法,这个方法会返回一个匿名类

  2. 该匿名类继承于Math类,包含一个multiply方法

  3. 当使用echo输出内容时,步骤如下

  4. 首先调用$math->multiply_sum()生成一个由匿名类创建的对象

  5. 接着执行->multiply(2),因为这个对象会调用匿名类的multiply方法并传递参数2

上面的代码中,Match类可以被外部类调用,匿名类可以被内部调用。

需要注意:内部类不需要也不推荐调用外部类,本例子这是展示证明内部类可以继承外部类的方式来调用外部类中呗声明为protected的方法。

补充:上面的列子针对匿名内部类调用外部类的栗子不明显,虽然不被推荐这么写,但是为了防止上面的栗子蒙,看一下例子.

<?php

class MathTest
{
    public $first_number = 20;

    public $second_number = 30;


    protected function add() : float
    {
        return $this->first_number + $this->second_number;
    }
}

class Math
{
    public $first_number = 10;

    public $second_number = 20;


    protected function add() : float
    {
        return $this->first_number + $this->second_number;
    }

    public function multiply_sum()
    {
        return new class() extends MathTest
        {

            public function multiply($third_number) : float
            {
                return $this->add() * $third_number;
            }
        };
    }
}

$math = new Math();

echo $math->multiply_sum()->multiply(2);

Last updated