有没有什么办法可以在PHP中定义抽象类属性?PHP抽象属性
abstract class Foo_Abstract {
abstract public $tablename;
}
class Foo extends Foo_Abstract {
//Foo must 'implement' $property
public $tablename = 'users';
}
有没有什么办法可以在PHP中定义抽象类属性?PHP抽象属性
abstract class Foo_Abstract {
abstract public $tablename;
}
class Foo extends Foo_Abstract {
//Foo must 'implement' $property
public $tablename = 'users';
}
有没有这样的东西定义一个属性。
您只能声明属性,因为它们是初始化时在内存中保留的数据的容器。
另一方面,函数可以被声明(类型,名称,参数)而不被定义(函数体缺失),因此可以被抽象化。
“摘要”只是表示声明了一些内容,但没有定义,因此在使用它之前,您需要定义它或者它变得毫无用处。
正如你可以通过只是测试你的代码已经发现:
Fatal error: Properties cannot be declared abstract in ... on line 3
没有,没有。不能在PHP中声明属性。
但是,你可以实现一个getter/setter函数的抽象,这可能是你在找什么。
属性不落实(特别是公共性),他们只是存在(或不):
$foo = new Foo;
$foo->publicProperty = 'Bar';
没有,有没有办法强制执行与编译器,你就必须使用运行时检查(比如,在构造函数中)为$tablename
变量,如:
class Foo_Abstract {
public final function __construct(/*whatever*/) {
if(!isset($this->tablename))
throw new LogicException(get_class($this) . ' must have a $tablename');
}
}
要强制执行对于Foo_Abstract的所有派生类,您必须使Foo_Abstract的构造函数为final
,从而防止重写。
你可以声明一个抽象的getter来代替:
abstract class Foo_Abstract {
abstract public function get_tablename();
}
class Foo extends Foo_Abstract {
protected $tablename = 'tablename';
public function get_tablename() {
return $this->tablename;
}
}
如上所述,不存在这样的确切定义。 我,但是,使用这种简单的解决办法来迫使子类来定义“抽象”属性:
abstract class Father
{
public $name;
abstract protected function setName(); // now every child class must declare this
// function and thus declare the property
public function __construct()
{
$this->setName();
}
}
class Son extends Father
{
protected function setName()
{
$this->name = "son";
}
function __construct(){
parent::__construct();
}
}
根据财产的情况下,如果我想强制在孩子的抽象对象属性的声明对象,我喜欢在抽象对象构造函数或setter/getter方法中使用关键字为static
的常量。
除此之外,如果重新定义,子对象将覆盖父对象属性和方法。 例如,如果在父级中声明一个属性为protected
,并且在孩子中重新定义为public
,则生成的属性是公共的。但是,如果该房产在父母中被宣布为private
,则该房产将保持private
,并且对于该孩子不可用。
http://www.php.net//manual/en/language.oop5.static.php
abstract class AbstractFoo
{
public $bar;
public function __construct()
{
$this->bar = static::BAR;
}
}
class Foo extends AbstractFoo
{
//const BAR = 'foobar';
}
$foo = new Foo; //Fatal Error: Undefined class constant 'BAR' (uncomment const BAR = 'foobar';)
echo $foo->bar;
这里最优雅的解决方案 –
我今天问自己同样的问题,我想补充我的两分钱。
我们希望abstract
属性的原因是要确保子类定义它们,并在它们没有的时候抛出异常。在我的具体情况中,我需要一些可以与static
盟友合作的东西。
理想我想是这样的:
abstract class A {
abstract protected static $prop;
}
class B extends A {
protected static $prop = 'B prop'; // $prop defined, B loads successfully
}
class C extends A {
// throws an exception when loading C for the first time because $prop
// is not defined.
}
我结束了这个实现
abstract class A
{
// no $prop definition in A!
public static final function getProp()
{
return static::$prop;
}
}
class B extends A
{
protected static $prop = 'B prop';
}
class C extends A
{
}
正如你所看到的,在A
我不定义$prop
,我却用它在static
获得者。因此,下面的代码工作
B::getProp();
// => 'B prop'
$b = new B();
$b->getProp();
// => 'B prop'
在C
,在另一方面,我不定义$prop
,所以我得到异常:
C::getProp();
// => Exception!
$c = new C();
$c->getProp();
// => Exception!
我必须调用getProp()
方法来获取异常我无法在课堂上加载它,但至少在我的情况下,它非常接近理想的行为。
我定义getProp()
为final
避免一些聪明的家伙(又称自己在6个月)的诱惑做
class D extends A {
public static function getProp() {
// really smart
}
}
D::getProp();
// => no exception...
这是非常巧妙的破解。希望这不需要在未来完成。 – CMCDragonkai
如果表名的值将不会在对象的生命周期内发生变化,以下将是一个简单但安全的实施。
abstract class Foo_Abstract {
abstract protected function getTablename();
public function showTableName()
{
echo 'my table name is '.$this->getTablename();
}
}
class Foo extends Foo_Abstract {
//Foo must 'implement' getTablename()
protected function getTablename()
{
return 'users';
}
}
的关键在这里是指定的字符串值“用户”和子类实现在getTableName时()直接返回。该函数模仿“只读”属性。
这与之前发布的使用附加变量的解决方案非常相似。我也喜欢Marco的解决方案,尽管它可能会更复杂一点。
+1:很好解释。 – hakre
没有明显的原因,'抽象'这个词不能用在* static *属性上 - 但意思稍有不同。例如,它可能表明一个子类必须为该属性提供一个值。 – frodeborli