58

PHP では抽象定数を使用できないことに気付きました。

子クラスに定数を強制的に定義させる方法はありますか (抽象クラスの内部メソッドの 1 つで使用する必要があります)。

4

7 に答える 7

32

Aconstantconstant; 私の知る限り、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();

バーはエラーを返します

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);
            }
        }
    }
}
于 2012-04-29T00:06:57.203 に答える
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();

これは、最初の説明からこれを行うと私が考えることができる最良の方法です。

于 2012-04-29T00:24:27.803 に答える
15

いいえ、それでも抽象メソッドなどの他の方法を試すことができます。

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
} 

ソース

于 2012-04-29T00:18:22.380 に答える