PHP抽象类子类的返回类型

问题描述 投票:0回答:5

PHP 中的抽象类如何返回扩展它的子类的类型?

abstract class MyAbstractClass {
    public static function fromID($id) : returnType { <======
        ...
    }
}

class MyChildClass extends MyAbstractClass {
    public function specificFunctionToThisClass(){
         ...
    }
    
}

$item = new MyChildClass()->fromID(3);
$item->specificFunctionToThisClass();

上面的例子过于简单了。

现在,如果我在任何子类中调用方法 fromID(var),它们将返回类型为 MyAbstractClass 的对象。我如何在 MyAbstractClass 中定义该函数的返回类型,以便无论哪个孩子调用该方法,它都会返回孩子的类而不是父类。

仅供参考,我知道我可以在每个子级中实现相同的函数,并将调用重定向到父级,但指定更具体的返回类型。长话短说,我的子类超过 100 个,仅在父类上定义它会容易得多,这样将来就不需要在每个子类上对代码进行任何更改

php inheritance abstract
5个回答
1
投票

returnType
应该是
MyAbstractClass
,没有任何实现(子实现)。

这可能是不可能的,但子级可以返回它自己的实例。对于动态配置,

$model
可以具有特定于父级和子级的配置。

使用

abstract class
abstract static function
让一切变得抽象:

abstract class Model {
    abstract static function fromArray( array $model ): Model;
    abstract static function fromID( int $id ): Model;
}

class LightSettings extends Model {
    public function __construct( array|null $config ) {
        parent::__construct( $config );
    }
    static function fromArray( array $model ): LightSettings {
        return new LightSettings( $model );
    } 
    static function fromID( int $$preset_id ): LightSettings {
        return new LightSettings( null )->load( $preset_id );
    }
    ...
}

构造函数显然也可以采用

int $$preset_id
,但它很灵活。


0
投票

本想这是一条评论,但评论太长了。

基于 Martin Zeitler 的答案(对不起,Martin,我在下面复制您的代码),在 Model 类中使用额外的静态方法:

abstract class Model {
    abstract static function fromArray( array $model ): Model;
    abstract static function fromID( int $id ): Model;

    // Common stuff for the fromArray factory
    protected static function populateFromArray(Model $model, array $modelArray): Model {
    // Do whatever is common here
    return $model;
}

class LightSettings extends Model {
    static function fromArray( array $model ): LightSettings {
        return parent::populateFromArray(new LightSettings(), $model);
    }
enter code here
    static function fromID( int $$preset_id ): LightSettings {
        // Similar implementation as in fromArray()
    }
    ...
}

0
投票

好的,你的问题是:

PHP 中的抽象类如何返回扩展它的子类的类型?

分别

我如何在中定义该函数的返回类型 MyAbstractClass 这样无论哪个孩子调用该方法都会 返回孩子的班级而不是父班级。

简短的回答是:你不能

继承是自上而下进行的...在任何情况下父类都不能知道它是子类。

想象一个框架。框架中的类旨在派生。但继承的类不是框架的作者编写的,而是一些下载了该框架并在他/她的项目中使用它的开发人员编写的。可能有成千上万的开发人员做了同样的事情,但使用了不同的子类。框架的作者如何知道所有的派生类?他不能,对吧?


0
投票

我想这可以通过使用

static
关键字来实现。不像静态变量 bu 中的
self
的替代品那样,意味着调用此方法的实例的类。出于某种原因,PHP 认为给两个不同的事物赋予相同的名称不是问题。

无论如何,定义的返回类型不会影响返回值。它只是检查返回值是否与我们想要的类型匹配。

所以答案是创建与子对象具有相同类的对象:

abstract class MyAbstractClass {
    public static function fromID($id) : MyAbstractClass { // This is on purpose. The child class is considered an instance of the parent class so it's fine
        return new static();
    }
}

class MyChildClass extends MyAbstractClass {
    public function specificFunctionToThisClass(){
         echo get_class($this);
    }
}

$item = (new MyChildClass())->fromID(3);
$item->specificFunctionToThisClass();   // prints 'MyChildClass'

0
投票

如果您的子类方法不是静态的,您将需要:

abstract class ModelAbstract {
    abstract function fromArray( array $array): object;
}
class ChildClass extends ModelAbstract {
    function fromArray( array $array ): ChildClass {
        //your code ...
        return $this;
    }
}

如果你的子类的方法是静态的,那么:

abstract class ModelAbstract {
    abstract static function fromArray( array $array): static;
}
class ChildClass extends ModelAbstract {
    static function fromArray( array $array ): ChildClass {
        //your code ...
        return new static();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.