简体   繁体   English

PHP获取子类方法

[英]PHP get child class methods

Is it possible in PHP to get the methods of an extended child class in a method declared in the parent class? 在PHP中是否可以在parent类中声明的方法中获取扩展child类的方法?

Here is a simple (maybe stupid) example: 这是一个简单的(也许是愚蠢的)示例:

<?php

class Vehicle{
    protected function moveForward(){
        // go ahead...
    }// moveForward

    public function getWhatCanIDo(){
        $actions = get_class_methods($this);
        return 'I can '.implode(', ', $actions).'<br/>';
    }// getWhatCanIDo
}


class Car extends Vehicle{
    protected function honk(){
        // honk...
    }// honk

    protected function turnHeadlightsOn(){
        // turn headlights on...
    }// turnHeadlightsOn

    protected function stopEngine(){
        // stop the engine
    }// stopEngine
}


class Submarine extends Vehicle{
    protected function submerge(){
        // sink...
    }// submerge

    protected function ping(){
        // ping...
    }// ping

    protected function fireTorpedos(){
        // DESTROY!!!
    }// fireTorpedos

    protected function stopEngine(){
        // stop the engine
    }// stopEngine
}


$volvo = new Car();
$uboat = new Submarine();

echo $volvo->getWhatCanIDo();
echo $uboat->getWhatCanIDo();

?>

The output what I expect is: 我期望的输出是:

I can moveForward, getWhatCanIDo, honk, turnHeadlightsOn, stopEngine
I can moveForward, getWhatCanIDo, submerge, ping, fireTorpedos, stopEngine

But instead It returns the the methos of the Vehicle class only, without the methods implemented in the extended class: 但是它只返回Vehicle类的方法,而没有在扩展类中实现的方法:

I can moveForward, getWhatCanIDo
I can moveForward, getWhatCanIDo

How could I get the extanded class methods? 我如何获得扩展的类方法?

Additional Infos: I have to solve this in PHP 5.2.14 The extended classes will have different numbers of methods with different method names so making Vehicle an abstract class wont help, because eg: I dont want Submarine to have honk method. 附加信息:我必须在PHP 5.2.14中解决此问题,扩展类将具有使用不同方法名称的不同数量的方法,因此使Vehicle成为抽象类将无济于事,因为:例如:我不希望Submarine具有honk方法。 I know I could make the getWhatCanIDo() an abstract method, but I'd like to implement this method "centrally" in the parent class, I dont want to oblige developers to write getWhatCanIDo() method for every extended class (In the future others may join or continue this project, and Its more failsafe to not let them implement this method again and again especially when the method does exactly the same thing.) 我知道我可以将getWhatCanIDo()作为抽象方法,但是我想在父类中“集中”实现该方法,我不想强​​迫开发人员为每个扩展类编写getWhatCanIDo()方法(以后其他人可能会加入或继续该项目,而且更安全的做法是不让他们一次又一次地实现此方法,尤其是在该方法执行完全相同的操作时。)

You should declare class Vehicle abstract, because it does not really exist and the real vehicles implement it. 您应该声明class Vehicle抽象class Vehicle ,因为它实际上并不存在,并且实际的车辆实现了它。

Then put whatCanIDo in Car and in Submarine , because you don't ask the vehicle what it can do, you ask the car. 然后将whatCanIDo放到CarSubmarine ,因为您不问车辆可以做什么,您要问汽车。

class Car extends Vehicle{
    public function getWhatCanIDo(){
        $actions = get_class_methods($this);
        return 'I can '.implode(', ', $actions).'<br/>';
    }// getWhatCanIDo
}

Update: 更新:

A yet different approach is to use the standard PHP library ReflectionClass : 另一种不同的方法是使用标准PHP库 ReflectionClass

$class   = new ReflectionClass('Vehicle');
$methods = $class->getMethods();

You need to overload the getWhatCanIDo() function in the Car & Submarine classes. 您需要在Car&Submarine类中重载getWhatCanIDo()函数。 You get the output because the function is executed in the Vehicle class. 因为该函数在Vehicle类中执行,所以您得到输出。

Overloading the method causes it to be executed in either the Car or Submarine class. 重载该方法会导致它在Car或Submarine类中执行。

You could also try get_class_methods(); 您也可以尝试get_class_methods(); More at http://www.php.net/manual/en/function.get-class-methods.php 有关更多信息, 请访问http://www.php.net/manual/zh/function.get-class-methods.php

This code is not tested, please, let me know if it works. 此代码未经测试,请让我知道它是否有效。

class MyBaseClass {
    //...
    public function getMethods($className) {
        return get_class_methods($className);
    }

    public static function getMethods($myObject) {
        return $myObject->getMethods(get_class($myObject));
    }
    //...
}

class MyInheritedClass {
    //...
}

$myBaseObject = new MyBaseClass(/*...*/);
$myInheritedObject = new MyInheritedClass(/*...*/);
echo var_dump(MyBaseClass::getMethods($myBaseObject));
echo var_dump(MyBaseClass::getMethods($myInheritedObject));

Inheritance is not proper tool here. 继承不是此处的适当工具。 You should use composition. 您应该使用合成。 Example: 例:

  1. Have separate objects Runner, Swimmer, WorkWithEngine, Submerge. 有单独的对象Runner,Swimmer,W​​orkWithEngine,Submerge。 All off them implements interface with getWhatCanIDo() method. 所有这些都使用getWhatCanIDo()方法实现接口。

  2. Create your new Vehiclas by composing them from Types from point one. 通过从第一点的类型组成它们来创建新的Vehiclas。 This object implements interface with getWhatCanIDo() method as well. 该对象也使用getWhatCanIDo()方法实现接口。

$submarine = new Submarine(); $submarine->addAblility(new Swimmer()); $submarine->addAblility(new WorkWithEngine()); $submarine->addAblility(new Submerge()); $submarine->whatCanIDo();

In any case do not use magic like get_class_methods those are constructs for frameworks creators it is not stuff for coding business logic. 无论如何,不​​要使用像get_class_methods这样的魔术,它们是框架创建者的构造,它不是用于编写业务逻辑的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM