5

I wanted to make an interface in PHP, but I didn't want it to be too restrictive on what argument type it would accept in one of the public methods. I didn't want to do

interface myInterface {
    public function a( myClass $a);
}

Because I may not want to pass it an instance of myClass. But, I do want to make sure that the object passed conforms to certain parameters, which I could accomplish by defining an interface. So I thought to specify classes that use interfaces, like so:

<?php

interface iA {}
interface iB {}

interface iC {
    public function takes_a( iA $a );
    public function takes_b( iB $b );
}

class apple implements iA {}
class bananna implements iB {}

class obj implements iC {
    public function takes_a( apple $a ) {}
    public function takes_b( bananna $b ) {}
}

But, I get the error PHP Fatal error: Declaration of obj::takes_a() must be compatible with iC::takes_a(iA $a) on line 15

Is there a way ensure that an argument accepts only a class of a certain interface? Or perhaps am I overthinking/over-engineering this?

3
  • when you implement your interface, the signature of the methods must be the same as in the interface. (public function takes_a( iA $a); in your obj class) but you can pass apple on this instance. $o = new obj(); $o->takes_a(new apple()); Commented Oct 14, 2015 at 5:33
  • @RaphaelMüller I don't understand what you're saying-- I know how to pass an apple object. Adding your line to the end of the script doesn't make it compile; it still complains about the function signature not matching. Commented Oct 14, 2015 at 5:40
  • 4
    see en.wikipedia.org/wiki/…. By narrowing down takes_a() to only allow "apple"s you disallow other "iA"s, but the interface iC demands to accept any iA as a parameter. Commented Oct 14, 2015 at 5:42

1 Answer 1

3

Your concept is totally correct. There is only one little wrong part. Your classes methods must have the same signature than specified in your interface.

as VolkerK said:

see wikipedia. By narrowing down takes_a() to only allow "apple"s you disallow other "iA"s, but the interface iC demands to accept any iA as a parameter. – VolkerK

with this in mind see the corrected code:

<?php

interface iA {
    function printtest();
}
interface iB {
    function play();
}

//since an interface only have public methods you shouldn't use the verb public
interface iC {
    function takes_a( iA $a );
    function takes_b( iB $b );
}

class apple implements iA {
    public function printtest()
    {
        echo "print apple";
    }
}
class bananna implements iB {
    public function play()
    {
        echo "play banana";
    }
}

//the signatures of the functions which implement your interface must be the same as specified in your interface
class obj implements iC {
    public function takes_a( iA $a ) {
        $a->printtest();
    }
    public function takes_b( iB $b ) {
        $b->play();
    }
}

$o = new obj();

$o->takes_a(new apple());
$o->takes_b(new bananna());
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.