扩展 PHP 静态类

2022-08-30 20:59:53

我已经在这个领域挣扎了好几天,我已经得出了一个结论,但是既然结论不是我想要的,在我放弃之前,我会试着看看别人怎么说。信心最后死去...

假设我们有一个超类(称为“超级”)和一个子类(称为“子”)。

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo self::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';
}

现在,您可能会期望由于Sub扩展了Super,Sub现在将继承Super的所有方法,但是,它似乎只接收对Sub方法的引用。

我这样说是因为如果我打电话:

Sub::get_class_name();

输出是“超级”,而不是“子”。

如果我打电话给:

Sub::get_title();

同样,输出是“超级”的,我甚至在Sub中声明了$title。

因此,这意味着当我调用继承的静态函数时,该函数的作用域将是超类,而不是被调用的类(即使您打印回溯,它也将显示调用是在超类上进行的!!!),并且为了获取范围作为正在进行调用的子类, 我需要在该子类中重新声明该方法。好吧,这种方式违背了扩展类的目的,不是吗?

所以我的问题是,我是否可以扩展一个静态类,调用一个继承的方法并具有子类的作用域?或者至少能够识别它的类名?如果没有,我为什么要扩展静态类呢?

谢谢!


答案 1

同样,这在 PHP 5.3.0 之前是不可能的。

后期静态绑定是在 PHP 5.3.0 中引入的,它允许您通过关键字完全按照自己的意愿执行操作。static

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo static::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';
}

get_class_name()仍将返回,尽管始终返回正在运行的方法声明的当前类(类似于,无论您是否包含它,它总是返回当前文件)。Super__CLASS____FILE__

为此,您别无选择,只能在类中重新声明函数。Sub

class Super {
    protected static $title = 'super';
    public static function get_class_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo static::$title;
    }
}
class Sub extends Super {
    protected static $title = 'sub';

    public static function get_class_name()        
    {
        echo __CLASS__;
    }
}

答案 2

您可以使用来获取要调用的类的类名,即使它是静态的。您不必在任何地方声明它。get_called_class()

来自安德鲁的例子:

class Super {
    public static function get_class1_name()        
    {
        echo __CLASS__;
    }
    public static function get_title()
    {
        echo get_called_class();
    }

}
class Sub extends Super {    
    public static function get_class2_name()        
    {
        echo __CLASS__;
    }

}
Sub::get_title(); // Echos Sub.
Sub::get_class1_Name(); // echos super
Sub::get_class2_Name(); // echos sub

因此,您不必声明任何变量。


推荐