有沒有什麼辦法可以在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