0

Given an object:

class MyObject implements MyInterface
{
   public function testMethod() {

   }
}

If there will be another class what uses an array of objects that implment MyInterface like this:

class Consumer
{
    public function __construct(array $myInterfaces)
    {
         foreach($myInterfaces as $myI) {
            $myI->testMethod();
         }
    }

}

How can i make my program design robust where i know that I can safely call testMethod() against the array elements?

Marty Wallace
  • 34,046
  • 53
  • 137
  • 200
  • 1
    Err, is this Java or PHP? – Tunaki Apr 16 '16 at 21:08
  • I think language agnostic. I added java tag as java from my opinion is very heavily based on oop and design patterns. But i had to write the example in some language – Marty Wallace Apr 16 '16 at 21:10
  • I don't understand the question. Why is there a PHP and Java snippet in there? Was exactly are you trying to do? Are you trying to communicate between Java and PHP somehow? – Tunaki Apr 16 '16 at 21:11
  • I don't see how an answer can be language agnostic. You need to specify which language you want to implement this in. – Mark B Apr 16 '16 at 21:13
  • So there is no generally accepted method of dealing with this and it is always language dependent? – Marty Wallace Apr 16 '16 at 21:15
  • Well, this problem can exist in PHP, Java, etc. when accepting an array of a base class or other interface. That's why instanceof and related operators exist. – Todd Christensen Apr 16 '16 at 21:17
  • Possible duplicate of [Checking if an instance's class implements an interface?](http://stackoverflow.com/questions/274360/checking-if-an-instances-class-implements-an-interface) – BudwiseЯ Apr 16 '16 at 21:18
  • Some languages support writing this, ie in Facebooks Hacklang (custom PHP) you could do `function foo(Vector $listOfMyInterfaces) { }` – JimL Apr 16 '16 at 21:32
  • yes, however i was attempting to get above specific language syntax and features and consider more design patterns and strategy to deal with this – Marty Wallace Apr 16 '16 at 21:35

3 Answers3

1

You can use the instanceof operator. For example:

foreach ($objects as $object) {
    if ($object instanceof Interface) {
        $object->testMethod();
    } else {
        throw new InvalidArgumentException('All objects must implement Interface.');
    }
}

In some languages, there are typed arrays, which can enforce this (such as Java.) The above is an example for PHP which does not have typed arrays.

Todd Christensen
  • 1,297
  • 8
  • 11
0

In PHP use the class_implements('MyObject') and cycle through the resulting array.

BudwiseЯ
  • 1,846
  • 2
  • 16
  • 28
0

You can make use of type hinting (type references) like so:

class Consumer {

    public function __construct(array $myInterfaces) {
        foreach ($myInterfaces as $myI) {
            $this->process($myI);
        }
    }

    private function process(MyInterface $m) {
        $m->testMethod();
    }

}

So to avoid a fatal error, process() will have to get an instance of MyInterface and by extension constructor argument has to be a collection of MyInterfaces.

You've effectively type constrained the collection constructor receives.

Weltschmerz
  • 2,166
  • 1
  • 15
  • 18
  • php7 would actually make process() throw a TypeError exception in case of a wrong type passed which gives a chance to your constructor to throw an exception with an appropriate error message describing whats wrong with the collection it got. – Weltschmerz Apr 17 '16 at 00:30