Abstrakcyjne stałe w PHP-zmuszają klasę potomną do zdefiniowania stałej
Zauważyłem, że w PHP nie można mieć stałych abstrakcyjnych.
Czy istnieje sposób, w jaki mogę zmusić klasę potomną do zdefiniowania stałej (którą muszę użyć w jednej z wewnętrznych metod klasy abstrakcyjnej) ?
4 answers
A constant
jest constant
; nie ma abstract
lub private
stałych w PHP, o ile wiem, ale możesz mieć pracę wokół:
Przykładowa Klasa Abstrakcyjna
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());
}
}
To będzie działać dobrze
class Foo extends Hello {
const CONSTANT_1 = 'HELLO_A';
const CONSTANT_2 = 'HELLO_B';
}
new Foo();
Bar zwróci błąd
class Bar extends Hello {
const CONSTANT_1 = 'BAR_A';
}
new Bar();
Songo zwróci błąd
class Songo extends Hello {
}
new Songo();
Klasa Enforcer
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);
}
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-25 09:26:22
Może to być trochę "włamanie", ale wykonuje zadanie z bardzo małym wysiłkiem, ale po prostu z innym Komunikatem o błędzie, jeśli stała nie jest zadeklarowana w klasie potomnej.
Deklaracja stałej self-referential jest poprawna składniowo i parsuje bez problemu, tylko rzucając błąd, jeśli ta deklaracja jest rzeczywiście wykonywana w czasie wykonywania, Więc deklaracja SELF-referential w klasie abstrakcyjnej musi być nadpisana w klasie potomnej, w przeciwnym razie będzie błąd krytyczny: Cannot declare self-referencing constant
.
W tym przykładzie, abstrakcyjna, nadrzędna klasa Foo
zmusza wszystkie swoje dzieci do zadeklarowania zmiennej NAME
. Ten kod działa poprawnie, wyprowadzając Donald
. Jeśli jednak Klasa potomna Fooling
nie zadeklarowała zmiennej , zostanie wywołany błąd krytyczny.
<?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;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-31 07:26:59
Niestety nie... stała jest dokładnie tym, co jest napisane na puszce, stała. Raz zdefiniowany nie może być ponownie zdefiniowany, więc w ten sposób nie można wymagać jego definicji poprzez abstrakcyjne dziedziczenie lub Interfejsy PHP.
Jednak... możesz sprawdzić, czy stała jest zdefiniowana w konstruktorze klasy nadrzędnej. Jeśli nie, rzuć wyjątek.
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();
To najlepszy sposób na zrobienie tego z twojego początkowego opisu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-29 00:24:27
Nie, ale można spróbować innych sposobów, takich jak metody abstrakcyjne:
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
}
Lub członkowie statyczni:
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
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-04 11:31:55