【问题标题】:PHP Override Interface signature in child class子类中的 PHP 覆盖接口签名
【发布时间】:2016-12-09 12:24:06
【问题描述】:

我有以下接口/类:

class Part {}
class Engine extends Part{}

interface CarsInterface {
    public function selectTimeLine(Part $object);
}

abstract class Car implements CarsInterface {}

class Hybrid extends Car {
    public function selectTimeLine(Engine $object) {}
}

如果 Engine 是“Part”的子类,为什么我不能在子签名(混合类)中使用 Engine 对象(我知道它在 Java 中可能......)

在 PHP 中实现此功能的正确方法是什么? 谢谢

【问题讨论】:

  • 有几个问题可以解决这个问题。这似乎是最有前途的,建议使用 instanceof:programmers.stackexchange.com/questions/227766/… 这是 SO 上的一个:stackoverflow.com/questions/13423494/… 您最好的选择可能是从参数声明中删除类型并使用 instanceof
  • @MontgomeryJean 我在环顾四周时看到了第二个答案......但是你能详细说明“instanceof”你能举个例子吗?
  • 没关系...看到了。

标签: php oop inheritance abstract-class signature


【解决方案1】:

简而言之,界面旨在通过为您的对象设置特定指令来为您提供这些限制。这样,在检查对象的功能或使用instanceof 时,您总是可以期望收到指定的内容。

没有“正确”的方法来实现您想要做的事情,但建议的方法是使用接口而不是特定的类定义进行类型提示。

这样,您始终可以保证所提供对象的可用方法。

interface TimeLineInterface { }

class Part implements TimeLineInterface { }

class Engine extends Part { }

interface CarInterface
{
    public function selectTimeLine(TimeLineInterface $object);
}

abstract class Car implements CarInterface { }

class Hybrid extends Car
{
   public function selectTimeLine(TimeLineInterface $object) { }
}

如果你想强制接受特定类型的对象作为对象的方法,你需要像这样检查对象实例。

class Hybrid extends Car
{
   public function selectTimeLine(TimeLineInterface $object) 
   {
       if (!$object instanceof Engine) {
            throw new \InvalidArgumentException(__CLASS__ . '::' . __FUNCTION__ . ' expects an instance of Engine. Received ' . get_class($object));
       }
   }
}

【讨论】:

    【解决方案2】:

    是的,PHP 很烂。 =)

    如果我没记错的话,你需要这样的东西:

    interface SomeInterface {
    }
    
    class Part implements SomeInterface  {}
    class Engine extends Part implements SomeInterface{}
    
    interface CarsInterface {
        public function selectTimeLine(SomeInterface $object);
    }
    
    abstract class Car implements CarsInterface {}
    
    class Hybrid extends Car {
        public function selectTimeLine(SomeInterface $object) {}
    }
    

    【讨论】:

    • 由于Part 实现SomeInterfaceEngine 扩展Part Engine 对象也将实现SomeInterface 参见我的示例和测试用例ideone.com/6CNdhk
    猜你喜欢
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    相关资源
    最近更新 更多