我可以为子类指定非严格的方法要求吗?

发布于 2024-07-10 22:28:29 字数 115 浏览 6 评论 0原文

我有一个基类,我想在其中指定子类必须具有的方法,但不自行实现它们。 但是,子类中的方法可能具有与基类中的定义不同数量的参数。

使用抽象方法尝试过此操作后,php 不允许这样做。 是否可以?

I have a base class in which I want to specify the methods a child class must have, but not implement them itself. However, the methods in a child class may have a different number of paramaters to the definition in the base class.

Having tried this with an abstract method, php doesn't allow this. Is it possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凉月流沐 2024-07-17 22:28:29

子类的函数可以向签名添加额外的可选参数,而不会导致错误:

abstract class Foo {
  abstract function bar($a);
}

class NewFoo extends Foo {

  function bar($a, $b = null) {
    //do something
  }
}

The child class's function can add extra, optional arguments to the signature without it causing errors:

abstract class Foo {
  abstract function bar($a);
}

class NewFoo extends Foo {

  function bar($a, $b = null) {
    //do something
  }
}
甜宝宝 2024-07-17 22:28:29

如果没有指定不带参数的抽象方法并要求子类方法通过 func_get_args 访问参数,我不知道这是如何可能的。

Short of specifying the abstract method with no parameters and requiring the subclassed method to access the args through func_get_args, I don't see how this would be possible.

趁微风不噪 2024-07-17 22:28:29

我想说这是 PHP 面向对象的弱点之一,它不是为处理这种用例而设计的。 它只是不意味着允许其重载方法

确实可以按照上面提到的两种方式进行您所谈论的一种黑客行为:

func_get_args()

或者,只是(就像提到的评论者)传递一个参数数组。 或者,您可以传入一个将参数作为数据成员的对象。 然后您可以为您的子方法扩展参数/参数对象。

关键是 PHP 是一种依靠宽容而非限制而繁荣的语言。 抽象类在 PHP 中有一个非常基本的实现。 如果您需要大量这样的结构,那么 PHP 确实可能不是最好的语言选择。

I would say this is one of the weak points of PHP's object orientation, that it wasn't designed to handle this kind of use case. It just wasn't meant to allow overloaded methods for its

It is indeed possible to do what you're talking about as a kind of hack, in both the way mentioned above with:

func_get_args()

or, just (like the commenter mentioned) pass in an array of arguments. Alternately you could pass in an object that has your arguments as data members. Then you could extend the parameter/argument object for your child method.

The point is that PHP is a language that thrives on permissiveness and not restriction. Abstract classes have a very basic implementation in PHP. If you have the need for a lot of structure like this, then PHP really might not be the best language choice.

还不是爱你 2024-07-17 22:28:29

我不认为这是您想要在生产中使用的答案,因为它会相当慢,但只是为了它,我尝试使用反射编写一些东西,这似乎有效。 您仍然会得到 E_STRICT,因为子类中的方法声明显然应该匹配。

class a {
    protected $requiredMethodsInSubclass = array( 'method1', 'method2', 'method3' );

    public function __construct() {
        $reflObject = new ReflectionObject($this);

        $className = $reflObject->getName();

        if ($className == __CLASS__) {
            //this class is being instanciated directly , so don't worry about any subclasses
            return;
        }

        foreach ($this->requiredMethodsInSubclass as $methodName) {
            try {
                $reflMethod = $reflObject->getMethod($methodName);
            } catch (ReflectionException $e) { //method not anywhere
                trigger_error("Method $methodName is not declared in class " . __CLASS__ . " or subclass $className", E_USER_ERROR);
                continue;
            }

            $declaringClass =  $reflMethod->getDeclaringClass();

            if ($declaringClass->getName() == __CLASS__) {
                //method is declared in this class, not subclass
               trigger_error("Method $methodName is not declared in subclass $className", E_USER_ERROR);
            }
        }
    }

    public function method1() {

    }

    public function method2($a) {

    }
 }



class b extends a {
    public function __construct() {
        parent::__construct();

        //some stuff
    }


    public function method2($a, $b, $c) {

    }

}



$b = new b();

I don't think this is an answer that you will want to use in production as it will be fairly slow, but just for the sake of it I tried to write something using Reflection, which seems to work. You will still get an E_STRICT because method declarations in subclasses are apparently supposed to match.

class a {
    protected $requiredMethodsInSubclass = array( 'method1', 'method2', 'method3' );

    public function __construct() {
        $reflObject = new ReflectionObject($this);

        $className = $reflObject->getName();

        if ($className == __CLASS__) {
            //this class is being instanciated directly , so don't worry about any subclasses
            return;
        }

        foreach ($this->requiredMethodsInSubclass as $methodName) {
            try {
                $reflMethod = $reflObject->getMethod($methodName);
            } catch (ReflectionException $e) { //method not anywhere
                trigger_error("Method $methodName is not declared in class " . __CLASS__ . " or subclass $className", E_USER_ERROR);
                continue;
            }

            $declaringClass =  $reflMethod->getDeclaringClass();

            if ($declaringClass->getName() == __CLASS__) {
                //method is declared in this class, not subclass
               trigger_error("Method $methodName is not declared in subclass $className", E_USER_ERROR);
            }
        }
    }

    public function method1() {

    }

    public function method2($a) {

    }
 }



class b extends a {
    public function __construct() {
        parent::__construct();

        //some stuff
    }


    public function method2($a, $b, $c) {

    }

}



$b = new b();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文