以前的解决方案,例如使用接口、将“门”限制为子类或复合类都可以。
有时,在定义类层次结构时,您可能会在后代类中找到可能实现或未实现的特性(方法或属性)。我提出的解决方案是,将该特性添加到基类中作为“抽象或虚拟特性”,并让每个类决定是否覆盖。
// check that in base classes,
// is common to have most stuff private or protected, not public
class Vehicle {
...
// using a protected variable field for properties
protected $_doors = array();
protected $_wings = array();
// you may want to use the methods or the "__call" way,
// Important, these are intentionally "protected", not "public"
protected /* array */ getDoors()
{
return $this->_doors;
} // /* array */ getDoors(...)
protected /* array */ setDoors(/* array */ p_doors)
{
$this->_doors = p_doors;
} // /* array */ SetDoors(...)
protected /* void */ function addDoor(/* array */ $args)
{
array_push($this->doors, $args[0]);
} // /* void */ function addDoor(...)
// you may want to use the methods or the "__call" way,
// Important, these are intentionally "protected", not "public"
protected /* array */ getWings()
{
return $this->_wings;
} // /* array */ getWings(...)
protected /* array */ setWings(/* array */ p_wings)
{
$this->_wings = p_wings;
} // /* array */ SetWings(...)
protected /* void */ function addWing(/* array */ $args)
{
array_push($this->wings, $args[0]);
} // /* void */ function addWing(...)
// these one is always public in all classes
public /* bool */ function supportsDoors()
{
return false;
}
// these one is always public in all classes
public /* bool */ function supportsWings()
{
return false;
}
} // class Vehicle
class Car extends Vehicle {
// these one is always public in all classes
public /* bool */ function supportsDoors()
{
return true;
}
public /* array */ getDoors()
{
return $this->_doors;
} // /* array */ getDoors(...)
// promoted from "protected" to "public"
public /* array */ setDoors(/* array */ p_doors)
{
$this->_doors = p_doors;
} // /* array */ SetDoors(...)
// promoted from "protected" to "public"
public /* void */ function addDoor(/* array */ $args)
{
array_push($this->doors, $args[0]);
} // /* void */ function addDoor(...)
} // class Car
class JetPack extends Vehicle {
// these one is always public in all classes
public /* bool */ function supportsWings()
{
return true;
}
// promoted from "protected" to "public"
public /* array */ getWings()
{
return $this->_wings;
} // /* array */ getWings(...)
// promoted from "protected" to "public"
public /* array */ setWings(/* array */ p_wings)
{
$this->_wings = p_wings;
} // /* array */ SetWings(...)
public /* void */ function addWing(/* array */ $args)
{
array_push($this->wings, $args[0]);
} // /* void */ function addWing(...)
} // class JetPack
class Boeing extends Vehicle {
// these one is always public in all classes
public /* bool */ function supportsDoors()
{
return true;
}
// these one is always public in all classes
public /* bool */ function supportsWings()
{
return true;
}
public /* array */ getDoors()
{
return $this->_doors;
} // /* array */ getDoors(...)
// promoted from "protected" to "public"
public /* array */ setDoors(/* array */ p_doors)
{
$this->_doors = p_doors;
} // /* array */ SetDoors(...)
// promoted from "protected" to "public"
public /* void */ function addDoor(/* array */ $args)
{
array_push($this->doors, $args[0]);
} // /* void */ function addDoor(...)
// promoted from "protected" to "public"
public /* array */ getWings()
{
return $this->_wings;
} // /* array */ getWings(...)
// promoted from "protected" to "public"
public /* array */ setWings(/* array */ p_wings)
{
$this->_wings = p_wings;
} // /* array */ SetWings(...)
public /* void */ function addWing(/* array */ $args)
{
array_push($this->wings, $args[0]);
} // /* void */ function addWing(...)
} // class JetPack
简历:“门”和“翼”在基类中被声明为“受保护的虚拟”,因此,所有后代类都将其设为受保护,但只有部分类实现了该功能, 并将功能、方法或属性公开。
作为补充说明,我个人不喜欢使用 PHP 的“快速而肮脏的虚拟”属性和方法,而是使用显式的“getMyProperty”和“setMyProperty”方法,或者“myMethod()” , 因为是最佳实践。我建议避免使用这些常见的“_call”功能。_