OOP - 如何让父函数执行一些默认功能?

OOP - How to make a parent function perform some default functionality?

在PHP中,我有一个抽象class(父),由子class扩展。我想让子class实现一个父的功能。当我调用 child 的已实现函数时,应该自动调用 parent 的默认功能。 可能吗?

例如,我想在每次调用子项的发送函数时创建父项的日志函数。

abstract class CommunicationService {
    // child classes must implement this
    abstract function send();
    abstract function receive();

    public function log($action) {
        echo 'Creating nice Log on = ' . $action;
    }
}

class ServiceA extends CommunicationService {
    public function send() {
        // Is it possible that the parent's logging functionality be invoked automatically by default?
        echo 'Send Message using Service A';
    }
    public function receive() {
        echo 'Receive Message using Service A';
    }
}

$serviceA = new ServiceA();
$serviceA->send(); // It should send message as well as create logs.
$serviceA->receive(); // It should just receive message and not log it.

此外,是否可以在父项中执行一些默认操作而在子项中执行其余功能?

此致。

任何扩展父级的 class 都需要其函数来显式调用父级 log() 函数,如下所示:

public function send() {
    // Is it possible that the parent's logging functionality be invoked automatically by default?
    parent::log( 'some text' ); // Tell the parent to log
    echo 'Send Message using Service A';
}

我将解决您问题的第二部分:"Is it possible to perform some default action in parent and the rest of the functionality in child?" 答案是肯定的,一种方法是使用 "design pattern" 称为 template method:

The template method pattern is a behavioral design pattern that defines the program skeleton of an algorithm in an operation, deferring some steps to subclasses.

我专门用 ~60 行(不计算评论)PHP MVC 微框架,来源在这里:https://github.com/dexygen/jackrabbitmvc/blob/master/barebones.lib.php

模板方法如下:

static function sendResponse(IBareBonesController $controller) {
  $controller->setMto($controller->applyInputToModel());
  $controller->mto->applyModelToView();
}

方法 $controller->setMtomto->applyModelToView 在源代码的其他地方实现,但是子 class 必须实现 $controller->applyInputToModel -- 请参阅源代码上方的注释.另请参阅我在 the inspiration for the framework

上所做的一篇文章

不确定这是否正是您所需要的。但是您可能想尝试使用链接机制:-

abstract class CommunicationService {
// child classes must implement this
abstract function send();
abstract function receive();

public function log($action) {
    echo 'Creating nice Log on = ' . $action;
    return $this;
}

}

class ServiceA extends CommunicationService {
public function send() {
    // Is it possible that the parent's logging functionality be invoked automatically by default?
    echo 'Send Message using Service A';
}
public function receive() {
    echo 'Receive Message using Service A';
}

}

$serviceA = new ServiceA();
$serviceA->log('send')->send(); // It should send message as well as create logs.
$serviceA->receive(); // It should just receive message and not log it.