Andi Gutmans wrote:

It depends what you call different signature. If you are talking about default arguments, we should consider allowing those as they don't change the isA relationship. However, if you want us to allow inheriting interfaces which truly differ in function prototypes than that would definitely be a strong no. You can never break the isA relationship.

I think at the heart of the problem (well, my problem) is the fact that using interfaces is restricting the way that classes are allowed to inherit from other classes.


-- Example (1) --

In more traditional PHP this works fine:

class A {
   function init() { ... }
   function doSomething($arg1, $arg2) { ... }
}

class B extends A { function doSomething($arg1, $arg2, $arg3, $arg4 = null) { ... }
function doSomethingElse($arg1) { ... }
}


$obj = new B;

// $obj instanceof B : YES
// $obj instanceof A :  YES -- but misleading

-- Example (2) --

Now when you throw interfaces into the mix, I won't be able to do that anymore -- even if I use two separate interfaces for class A and class B.

interface IA {
 function init();
 function doSomething($arg1,$arg2);
}

interface IB {
   funciton init();
   function doSomething($arg1, $arg2, $arg3, $arg4 = null);
   function doSomethingElse($arg1);
}

class A implements IA {
  // same class body as above
}

class B extends A implements IB {
 // same class body as above
}

Now I get fatal errors, because class B is inheriting functionality from A that is required by the interface IB. Actually, I think what is happening (can someone confirm this?) is that class B is being forced to implement both IA and IB, and because interfaces (unlike classes) are not allowed to override methods class B cannot implement both interfaces.

Posslble solutions to this (in PHP engine):

- do not inherit interfaces: force "implements" to be explicit for each class, so that in this case class B would not implement interface IA. This doesn't seem like a particularly good solution, but it would work [I think].

- allow interfaces to override methods. I think to be consistent with PHP class behavior this is still the best option. Just like PHP classes can override methods, I think interfaces should be allowed. It's just as easy to break "instanceof" using class inheritance (as I showed in Example 1) as it would be to break it using interface overrides. In Java this isn't an issue of course because of overloading.

Does anyone have any other suggestions for this? I agree that radically breaking signatures in subclasses is probably not "good practice" but in light of the fact that PHP doesn't support method overloading, I don't really see an alternative. My take on it is that this is just a limitation of PHP -- and I'm fine with that. I think to be consistent it would be good if interfaces supported the same behavior -- again, agreeing all the while that academically it's not the "best" design.

Hans

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Reply via email to