是否可以在PHP界面中创建可选方法?

时间:2015-11-24 10:44:21

标签: php oop interface

我正在使用PHP开展项目。我有几个类需要实现一个接口。有些类不需要实现接口中定义的所有方法。是否有可能只以更清洁的方式实施某些方法。

3 个答案:

答案 0 :(得分:2)

接口指定 必须 由实现它的类实现的方法,你不能跳过一些,尽管你可以创建其他的....你可以做的是将你的界面分成几个“较小”的界面,并根据需要设置实现一个 或更多 的类,如下例3中的PHP Docs

答案 1 :(得分:0)

接口用于一组类必须执行相同结构的情况。比实现一个接口来强制执行某些属性或方法。

如果有一些类,那就不需要有一些接口方法,所以这个类不应该实现接口。

如果您必须违反规则来实施某些内容,则需要分析您的实施。

答案 2 :(得分:0)

通常,接口定义了您的类必须实现的方法。因此,根据定义,强制实现您不想实现的方法会使接口的概念无效。

我看到两种情况:

1。分体式接口

通过使用多个较小的接口来组合您的类接口可为您提供很多控制权,但可能会导致整个地方的接口都非常小。

示例

考虑一个请求类,它可能有一个 json 主体或一些表单参数。您的请求可能不会同时拥有,但您仍然希望提供接口来共享公共类布局。使用分离的接口,你可以有

<?php

interface Request {
    public function getHeaders(): array;
}

<?php

interface JsonRequest extends Request {
    public function getJsonBody(): string;
}

<?php

interface FormRequest extends Request {
    public function getFormParameters(): array;
}

然后用它来指定你的请求类接口:

<?php

class MyRequest implements JsonRequest {
    public function getHeaders(): array
    {
        return ['some' => 'headers'];
    }

    public function getJsonBody(): string
    {
        return json_encode(['some' => 'content']);
    }
}

这种方法为您提供了清晰且富有表现力的接口,以及只需要实现其所需内容的类。为了查看请求是否具有 json 正文,您可以检查接口:

if ($request instanceof JsonRequest) { //...

2.抽象类作为默认提供者

允许您拥有一个通用接口和一些不需要在任何地方实现的方法的第二种方法是接口和抽象类的组合。

示例

对于与上面相同的示例,此方法将为您提供一个接口、一个抽象类以及两者的具体实现。在示例中,我还将默认值设置为 null,以便稍后可以对方法内容进行适当的检查。

界面:

<?php

interface RequestInterface {
    public function getHeaders(): array;

    public function getJsonBody(): ?string;

    public function getFormParameters(): ?array;
}

使实现成为可选的抽象类:

<?php

abstract class AbstractRequest implements RequestInterface {
    public function getJsonBody(): ?string
    {
        return null;
    }

    public function getFormParameters(): ?array
    {
        return null;
    }
}

然后是实际的请求,这又是一个 json 请求。

<?php

class MyRequest extends AbstractRequest {
    public function getHeaders(): array
    {
        return ['some' => 'headers'];
    }

    public function getJsonBody(): string
    {
        return json_encode(['some' => 'content']);
    }
}

为了查看请求是否具有 json 正文或某些表单参数,您可以在此示例中检查 null

if ($request->getJsonBody() !== null) {...

结论

这两种方式在技术上都是有效的(意味着两种方式都可以工作,但不是两种都是好的代码)并且使用可选方法导致相同的类布局。这两种技术各有利弊。

使用分离的接口提供了隐式类型安全,并且更容易依赖接口(也用于其他下游决策,例如如何通过接口实现解析器或处理器,如何处理依赖注入等)。这种方法更简洁,并产生更好的代码。但它也可能导致为许多具有不同专业的类似类提供许多接口。考虑还有用于请求方法的接口,一些其他选项,可能还有一些编码等等。如果你想(!),你最终会得到很多界面和很少的监督。

使用抽象类来提供默认实现是围绕接口的想法工作的,可能会削弱您的代码可用性。每当您在应用程序的某处发现一些 AbstractRequest 时,您可能不再依赖它的接口,因为它可能已经实现也可能没有实现它们。因此,无论是否存在实际实现,您都必须检查抽象类为其提供默认值的所有方法。 (旁注:否则你将不得不检查接口,所以你无论如何都必须检查一些东西)把这些缺点放在一边(事实上它并不是真正的实现方式)还有好处,您将拥有一个包含所有方法定义的接口,然后是一个提供一些默认值的抽象类。易于理解 - 在某些情况下可能比许多界面更容易。 (旁注:也许你甚至可以在第二种情况下完全放弃接口,只要抽象类中没有不能声明的东西。)