我有一些抽象类 MyClass 和 foo 方法。当有人从这个类中继承并重写此方法时,从子类调用此方法很重要。所以我希望在这种情况发生时显示警告。但是我不能修改子类,因为它不是我设计的。此外, foo 方法可以覆盖但不必重写。
在代码中,调用FirstClass::foo()
会导致警告,但SecondClass::foo()
不会。我怎么能这样做?
abstract class MyClass {
public function foo() {
// do something important
}
}
class FirstClass extends MyClass {
public function foo() {
// do something special
}
}
class SecondClass extends MyClass {
public function foo() {
parent::foo ();
// do something special
}
}
答案 0 :(得分:0)
你不能这样做。你可以在你的抽象类中添加一些标志并检查它,但这是错误的。
我建议你改用Template method pattern。
abstract class MyClass {
final public function foo() {
// do something important
$this->_overridableMethod();
}
abstract protected function _overridableMethod();
}
class FirstClass extends MyClass {
protected function _overridableMethod(){
// do something special
}
}
答案 1 :(得分:0)
以下是我将如何执行此操作的骨架示例:
interface VehicleInterface
{
public function move($x, $y);
public function refuel($station);
}
interface FlyableInterface
{
public function takeoff();
public function land();
}
abstract class AbstractVehicle implements VehicleInterface
{
/**
* Implementation to refuel at station
*/
public function refuel($station)
{
}
}
class Car extends AbstractVehicle
{
/**
* Implementation to move by following a road.
*/
public function move($x, $y)
{
}
}
class Plane extends AbstractVehicle implements FlyableInterface
{
/**
* Implementation to move by means of flying.
*/
public function move($x, $y)
{
}
/**
* Override of AbstractVehicle::refuel, landing required first.
*/
public function refuel($station)
{
$this->land();
parent::refuel($station);
}
/**
* Implementation for plane to take off.
*/
public function takeoff()
{
}
/**
* Implementation to land the plane.
*/
public function land()
{
}
}
$vehicles = array(new Car(), new Plane());
$x = '145';
$y = '751';
foreach($vehicles as $vehicle) {
if($vehicle instanceof FlyableInterface) {
$vehicle->takeoff();
$vehicle->move($x, $y);
$vehicle->land();
} else {
$vehicle->move($x, $y);
}
}
最后的执行脚本打算根据每个类实现的方法对每个车辆执行相同的任务。飞机和汽车都实施相同的move
方法,并且它们都继承了相同的refuel
方法,但是飞机需要先降落。
执行脚本将通过检查它是否是特定接口的实例来检测支持哪些方法。
对于实践中的示例,Symfony2类Command
有一个名为ContainerAwareCommand
的变体。通过扩展它,框架知道注入服务容器,因为支持的方法是由子类继承或实现的。