PHP接口有属性吗?

epggiuax  于 2023-01-08  发布在  PHP
关注(0)|答案(6)|浏览(158)

PHP中的接口有属性吗,还是只有方法?

toe95027

toe950271#

您可以在DocBlock中声明接口的属性。IDE会提示接口的这些属性(PhpStorm会这样做),但这不会强制在实现类中实际实现这些字段。

/**
 * @property string $password
 * @property string $username
 */
interface IUserDocument
{

}
nhaq1z21

nhaq1z212#

这取决于你所指的“属性”。如果你指的是实际的字段,那么不,它们不是。如果你指的是C#中的属性,那么是的,它们可以(因为属性访问器无论如何都是访问器方法的语法糖)。(当然,在每种情况下,都没有为get/setadd/remove访问器指定实现)。

更新:由于PHP没有get/set访问器意义上的属性,那么对您问题的回答是否定的。接口不能携带自己的数据/状态。

nzk0hqpo

nzk0hqpo3#

PHP中的接口可能只包含没有方法体的公共方法签名。它们也可能包含常量。但仅此而已。
参见http://www.php.net/manual/en/language.oop5.interfaces.php
接口是用interface关键字定义的,和标准类的方式一样,但是没有定义任何方法的内容。[...]接口中声明的所有方法都必须是公共的,这就是接口的本质。[...]接口有常量是可能的。接口常量的工作原理与类常量完全一样,只是它们不能被类/继承它的接口。

rslzwgfq

rslzwgfq4#

PHP接口可以有常量,但不能有属性(示例变量)。如果你不需要修改你的“属性”,你可以用常量代替。

igsr9ssn

igsr9ssn5#

我迟到了,但这可能对将来的人有所帮助...接口不应该有属性,因为它对应于实现(即类)。属性必须用于表示类的内部状态。接口更像是一种类型,定义了该类型可以做什么或不可以做什么(方法)。
对象必须具有足够的通用性和解耦性,才能对其类型给予响应。

**参考书:**设计模式- Erich Gamma

使用接口的方式(〉8的语法)

<?php

interface Transport {
    public function ticketCode();
}

interface Vehicle {
    public function start();
    public function stop();
    public function getStatus();
}

class Cab implements Transport, Vehicle {
    private string $ticket;
    private string $status;
    
    function __construct(){
        $this->ticket = time();
        $this->status = "off";
    }

    public function start(){
        $this->status = 'on';
    }
    
    public function stop(){
        $this->status = 'off';
    }
    
    public function getStatus(){
        echo "The status is: {$this->status}";
    }
    
    public function ticketCode() {
        echo "The ticket code is: {$this->ticket}";
    }
}

class Motorcycle implements Vehicle {
    private string $status;
    
    function __construct(){
        $this->status = "off";
    }

    public function start(){
        $this->status = 'on';
    }
    
    public function stop(){
        $this->status = 'off';
    }
    
    public function getStatus(){
        echo "The status is: {$this->status}";
    }
}

$cab = new Cab();
echo " > cab is a Transport? " . ($cab instanceof Transport ? 'yes':'no') . " || cab is a Vehicle? " .  ($cab instanceof Vehicle ? 'yes':'no'); 

$motorcycle = new Motorcycle();
echo " > motorcycle is a Transport? " . ($motorcycle instanceof Transport ? 'yes':'no') . " || motorcycle is a Vehicle? " . ($motorcycle instanceof Vehicle?'yes':'no');

在前面的示例中,我们可以看到接口如何定义类将采用的类型(一个类可以有多个类型),类负责定义这些类型如何实现和交互。因此,这解释了为什么接口不允许有属性(不,这不是语言错误),它实际上是应该管理和定义状态的类(属性)。谁必须操纵他们和改变他们的值是对象或类示例。接口只是说,它必须实现的类被认为是某种类型,一个接口一定不做的事情。

function startVehicle(Vehicle $vehicle){
    $vehicle->start();
}

$motorcycle->getStatus();
$cab->getStatus();
startVehicle($motorcycle);
startVehicle($cab);
$motorcycle->getStatus();
$cab->getStatus();

使用接口将允许你做一些事情,如多态性或按类型处理对象(类示例或你想调用它的任何东西),而不管它们来自哪个类,只要它实现了“X”类型,它就将是一个有效的对象来处理它的接口(在上面的例子中,类型将是Vehicle)。
接口确实是一个接口,我把它叫做类型,这样可以更容易理解它的方法。

**简历 *

如果你想要一个带有属性的接口,那么你的解决方案设计得很糟糕,需要重新考虑一下。也许我应该考虑类继承。
考虑到一个类同样可以被视为一个类型,或者我提到的类型,这个解释可能看起来有争议,但是这个概念要理解起来稍微复杂一些,我邀请你阅读前面提到的书,它可以更好地解释这个区别。

vs3odd8k

vs3odd8k6#

在接口中需要属性的[有效]原因是指定DTO类具有某个方面,例如IOrderable { OrderDate,OrderStatus }、IDeliverable { DeliveryAddress,Route,...}等。该方面可以在许多DTO中使用,例如销售订单、工作订单、销售发票等。DTO类可以支持多个方面。即多重继承,这在数据类(而不是代码类)中是可取的。此后,DTO的客户机被确保可以通过该方面(接口契约)查看DTO。该模式遵守所有5个SOLID原则。
在PHP中,与接口属性最接近的是traits http://php.net/manual/en/language.oop5.traits.php。与接口类似,traits不能示例化,但可以直接在类中使用而无需实现它们。

相关问题