PHP - защищенный / абстрактный метод для использования класса, объявленного в дочернем классе - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть абстрактный класс, в котором я хочу вызвать метод из класса, который объявлен в дочернем (расширяющем) классе.Пример выглядит следующим образом:

Абстрактный класс:

abstract class NumberGenerator
{
    protected function generate($input){
        return MyClass::MyMethod($input);
    }
}

Мой дочерний / расширяющий класс:

use TomsFolder\MyClass;
use MyFolder\NumberGenerator;

class TomsNumberGenerator extends NumberGenerator
{
    public function generate(string $applicantId): string
    {   
        return $this->generate();
    }
}

Другой дочерний / расширяющий класс:

use DavesFolder\MyClass;
use MyFolder\NumberGenerator;

class DavesNumberGenerator extends NumberGenerator
{
    public function generate(string $applicantId): string
    {   
        return $this->generate();
    }
}

Итак, я хочу вызвать MyClass :: MyMethod в NumberGenerator.Однако он импортируется только в TomsNumberGenerator.

Причина, по которой я хочу это сделать, заключается в том, что у меня есть классы, такие как DavesNumberGenerator, который вызывает другой MyClass.

Когда я пытаюсь это сделать, я получаю 'MyClass не найден в NumberGenerator '.Есть ли способ заставить эту работу?

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Вы должны использовать интерфейс для этого.Вы можете сделать следующее

  1. Создать MyClassInterface
interface MyClassInterface {
    public function MyMethod();
}
Реализовать этот интерфейс в некоторых классах
class MyClass1 implements MyClassInterface {
    public function MyMethod() {
        // implementation
    }
}

class MyClass2 implements MyClassInterface {
    public function MyMethod() {
        // implementation 2
    }
}
Добавить абстрактный метод к NumberGenerator
abstract class NumberGenerator {
    abstract protected function GetMyClass(): MyClassInterface;

    protected function generate($input){
        return $this->GetMyClass()->MyMethod($input);
    }
}
Реализация GetMyClass функции внутри дочерних классов
class TomsNumberGenerator extends NumberGenerator
{
    protected function GetMyClass(): MyClassInterface {
        return new MyClass1();
    }
}
class DavesNumberGenerator extends NumberGenerator
{
    protected function GetMyClass(): MyClassInterface {
        return new MyClass2();
    }
}

PS Если вы хотите использовать статические, вы можете изменить абстрактные внутри NumberGenerator класса,изменить string.В этом случае ваш generate будет выглядеть так:

protected function generate($input){
    return call_user_func($this->GetMyClass() . '::MyMethod', [$input]);
}
0 голосов
/ 06 февраля 2019

Попробуйте поместить оператор пространства имен use перед фактическим классом:

NumberGenerator.php

use MyFolder\MyClass;

abstract class NumberGenerator
{
    protected function generate($input){
        return MyClass::MyMethod($input);
    }
}

РЕДАКТИРОВАТЬ

Попробуйте это:

NumberGenerator.php

abstract class NumberGenerator
{
    protected function generate($class_name, $input){
        return call_user_func($class_name . '::MyMethod', $input);
    }
}

TomsNumberGenerator.php

use TomsFolder\MyClass;
use MyFolder\NumberGenerator;

class TomsNumberGenerator extends NumberGenerator
{
    public function generate(string $applicantId): string
    {   
        return $this->generate(get_class(new MyClass()), $applicantId);
    }
}
...