在PHP OOP中调用子方法

在PHP OOP中调用子方法,php,inheritance,Php,Inheritance,我正在创建一组用于测试某些数据的类-我有一个基类Test: class Test { protected $data; public function __construct($data) { $this->data = $data; } public function Run() {} } 然后是一系列扩展Test的类,例如TestForX: class TestForX extends Test { public functi

我正在创建一组用于测试某些数据的类-我有一个基类
Test

class Test {
    protected $data;
    public function __construct($data) {
        $this->data = $data;
    }
    public function Run() {}
}
然后是一系列扩展Test的类,例如
TestForX

class TestForX extends Test { 
    public function Run() {
        // do test code
    }
}
我想给我的跑步方法增加一些计时。我知道我可以为基类添加
startTiming
endTiming
方法,并在扩展类中调用
parent::startTiming()
parent::endTiming()
,但我已经编写了大量测试

有没有可能扭转这种局面,在我的基类中使用类似于
child::Run
的东西

class Test {
    public function Run() {
        $this->startTime = microtime(true);
        child::Run();
        $this->endTime = microtime(true);
    }
}

这将允许我通过在基类中包装方法来保持子类的干净。目前,我正在为
Test::Go
创建一个基类,它调用
$this->Run()

如果您可以随意更改对测试类的调用,您可以添加另一个函数来包装您的行为

public function runTest(){
    $this->startTime = microtime(true);
    $this->Test();
    $this->endTime = microtime(true);
}

如果您可以随意更改对测试类的调用,那么可以添加一个包装您的行为的其他函数

public function runTest(){
    $this->startTime = microtime(true);
    $this->Test();
    $this->endTime = microtime(true);
}

我认为不可能调用与父方法同名的子方法。首先,假设子类重写方法是不好的设计。强制一个子类来实现一个方法就是定义一个父抽象方法,但在这种情况下,您就是不能。Run()方法已在父类中实现

您应该使用抽象并使用不同的名称

下面是一个可能对您有用的实现。您可以将基类定义为抽象类,TestForX将扩展Test类,并在TestForX实例上调用Run()


我认为不可能调用与父方法同名的子方法。首先,假设子类重写方法是不好的设计。强制一个子类来实现一个方法就是定义一个父抽象方法,但在这种情况下,您就是不能。Run()方法已在父类中实现

您应该使用抽象并使用不同的名称

下面是一个可能对您有用的实现。您可以将基类定义为抽象类,TestForX将扩展Test类,并在TestForX实例上调用Run()



这看起来不像phpunit。您的测试框架是否有测试方法startUp()和tearDown()方法的概念?如果是这样,我会把它放在基类中,尽管测试框架本身会带来时间开销。谢谢,但这是为了测试文档结构(例如DOM),而不是单元测试。FWIW,您的类
test
不应该有一个名为
test
的方法;这是一种古老但仍受支持的声明构造函数的方法,总有一天会让你吃一顿苦头。谢谢@deceze,说得好。我将更新我的问题。另外,无需致电
parent::startTiming
$this->startTiming
也可以不,如果您在子类中重写方法
Test
,这是不可能的。您将需要使用另一个方法名,或者重新构造您的通用逻辑。您的测试框架是否有测试方法startUp()和tearDown()方法的概念?如果是这样,我会把它放在基类中,尽管测试框架本身会带来时间开销。谢谢,但这是为了测试文档结构(例如DOM),而不是单元测试。FWIW,您的类
test
不应该有一个名为
test
的方法;这是一种古老但仍受支持的声明构造函数的方法,总有一天会让你吃一顿苦头。谢谢@deceze,说得好。我将更新我的问题。另外,无需致电
parent::startTiming
$this->startTiming
也可以不,如果您在子类中重写方法
Test
,这是不可能的。您需要使用另一个方法名称,或者重新构造您的常规逻辑。谢谢,但在我的问题中,我已经说过这就是我目前正在做的。我相信Joffrey建议将
runTest()
添加到父类中。@AlexBlex在我的问题中,我描述了“为Test::Go创建一个基类,它调用$this->Run()-我非常感谢乔弗里所做的努力,但它确实重复了我已经说过的话。@AdamHopkinson你在回答和我的评论之后编辑了这个问题,因此,我在新版中再次重复它-如果父方法被子类的
TestForX::Run
覆盖,则无法调用父方法
Test::Run
,除非您在子类中通过
parent::Run
显式调用它。谢谢,但在我的问题中,我说过这就是我目前正在做的。我相信Joffrey建议将
runTest()
添加到父类中。@AlexBlex在我的问题中,我描述了“为Test::Go创建一个基类,它调用$this->Run()”-我非常感谢Joffrey所做的努力,但它确实重复了我已经说过的话。@AdamHopkinson你在回答和我的评论之后编辑了这个问题,因此,我在新版中再次重复这一点-如果父方法被子类的
TestForX::Run
覆盖,则无法调用父方法
Test::Run
,除非您在子类中通过
parent::Run
显式调用它。