Ale*_*lex 44 php constants abstract
我注意到你不能在PHP中使用抽象常量.
有没有办法可以强制子类定义一个常量(我需要在其中一个抽象类内部方法中使用)?
Web*_*ery 46
这可能是一个"黑客",但只需很少的努力就可以完成工作,但如果未在子类中声明常量,则只需使用不同的错误消息.
自引用常量声明在语法上是正确的并且解析没有问题,只有在运行时实际执行该声明时才抛出错误,因此必须在子类中重写抽象类中的自引用声明否则会出现致命错误:Cannot declare self-referencing constant.
在此示例中,abstract,parent类Foo强制其所有子节点声明变量NAME.此代码运行正常,输出Donald.但是,如果孩子上课Fooling也没有声明变量,会触发致命的错误.
<?php
abstract class Foo {
    // Self-referential 'abstract' declaration
    const NAME = self::NAME;
}
class Fooling extends Foo {
    // Overrides definition from parent class
    // Without this declaration, an error will be triggered
    const NAME = 'Donald';
}
$fooling = new Fooling();
echo $fooling::NAME;
Bab*_*aba 28
A constant是一个constant; 据我所知,PHP中没有abstract或private常量,但你可以有一个解决方法:
样本抽象类
abstract class Hello {
    const CONSTANT_1 = 'abstract'; // Make Abstract
    const CONSTANT_2 = 'abstract'; // Make Abstract
    const CONSTANT_3 = 'Hello World'; // Normal Constant
    function __construct() {
        Enforcer::__add(__CLASS__, get_called_class());
    }
}
这样运行正常
class Foo extends Hello {
    const CONSTANT_1 = 'HELLO_A';
    const CONSTANT_2 = 'HELLO_B';
}
new Foo();
Bar会返回Error
class Bar extends Hello {
    const CONSTANT_1 = 'BAR_A';
}
new Bar();
Songo 将返回Error
class Songo extends Hello {
}
new Songo();
执行者类
class Enforcer {
    public static function __add($class, $c) {
        $reflection = new ReflectionClass($class);
        $constantsForced = $reflection->getConstants();
        foreach ($constantsForced as $constant => $value) {
            if (constant("$c::$constant") == "abstract") {
                throw new Exception("Undefined $constant in " . (string) $c);
            }
        }
    }
}
Jam*_*low 19
不幸的是,不是......一个常数正是它在锡上所说的,不变的.一旦定义,就无法重新定义,因此以这种方式,不可能通过PHP的抽象继承或接口来定义它的定义.
但是......您可以检查是否在父类的构造函数中定义了常量.如果没有,则抛出异常.
abstract class A
{
    public function __construct()
    {
        if (!defined('static::BLAH'))
        {
            throw new Exception('Constant BLAH is not defined on subclass ' . get_class($this));
        }
    }
}
class B extends A
{
    const BLAH = 'here';
}
$b = new B();
这是我从最初的描述中想到的最佳方式.
不,但你可以尝试其他方法,如抽象方法:
abstract class Fruit
{
    abstract function getName();
    abstract function getColor();
    public function printInfo()
    {
        echo "The {$this->getName()} is {$this->getColor()}";
    }
}
class Apple extends Fruit
{
    function getName() { return 'apple'; }
    function getColor() { return 'red'; }
    //other apple methods
}
class Banana extends Fruit
{
    function getName() { return 'banana'; }
    function getColor() { return 'yellow'; }
    //other banana methods
}  
或静态成员:
abstract class Fruit
{
    protected static $name;
    protected static $color;
    public function printInfo()
    {
        echo "The {static::$name} is {static::$color}";
    }
}
class Apple extends Fruit
{
    protected static $name = 'apple';
    protected static $color = 'red';
    //other apple methods
}
class Banana extends Fruit
{
    protected static $name = 'banana';
    protected static $color = 'yellow';
    //other banana methods
}