# Using child classes/interfaces as desired type hints

- Thread: https://externals.io/message/49881
- Original archive: https://news-web.php.net/php.internals/49881
- Started by Nathan Nobbe on 2010-10-07T05:56:34+00:00
- Messages: 4
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #49881 — Nathan Nobbe — 2010-10-07T05:56:34+00:00

URL: https://externals.io/message/49881#49881

Hi,

Probly rehashing an old conversation here, but I'm wondering why the
following isn't supported

<?php
abstract class AbstractServer {}
class ConcreteServer extends AbstractServer {}

abstract class AbstractClient {
  abstract function doStuff(AbstractServer $o);
}

class ConcreteClient extends AbstractClient {
  function doStuff(ConcreteServer $o) {}
}
?>

This results in a fatal
Fatal error: Declaration of ConcreteClient::doStuff() must be compatible
with that of AbstractClient::doStuff() in
/Users/quickshiftin/gitRepos/timberline/php-api-v15-client/testOverride.php
on line 11

I was reading a few posts from way back when

http://marc.info/?t=107774904800001&r=1&w=2

yet still find myself wondering.  I think it can be said here that if
there's a contract defined by AbstractClient::doStuff, that same contract is
honored by ConcreteClient::doStuff.  I also think changing the language to
support this notion wouldn't raise BC issues for the most part (at all?)
since at the moment you're forced to move to the lowest common denominator
in the tree, in this case

class ConcreteClient extends AbstractClient {
  function doStuff(AbstractServer $o) {}
}

your feedback appreciated,

-nathan

---

## #49882 — Ferenc Kovacs — 2010-10-07T07:24:56+00:00

URL: https://externals.io/message/49881#49882 · In reply to: #49881

> Hi,
>
> Probly rehashing an old conversation here, but I'm wondering why the
> following isn't supported
>
> <?php
> abstract class AbstractServer {}
> class ConcreteServer extends AbstractServer {}
>
> abstract class AbstractClient {
>  abstract function doStuff(AbstractServer $o);
> }
>
> class ConcreteClient extends AbstractClient {
>  function doStuff(ConcreteServer $o) {}
> }
> ?>
>
> This results in a fatal
> Fatal error: Declaration of ConcreteClient::doStuff() must be compatible
> with that of AbstractClient::doStuff() in
> /Users/quickshiftin/gitRepos/timberline/php-api-v15-client/testOverride.php
> on line 11
>
> I was reading a few posts from way back when
>
> http://marc.info/?t=107774904800001&r=1&w=2
>
> yet still find myself wondering.  I think it can be said here that if
> there's a contract defined by AbstractClient::doStuff, that same contract
> is
> honored by ConcreteClient::doStuff.  I also think changing the language to
> support this notion wouldn't raise BC issues for the most part (at all?)
> since at the moment you're forced to move to the lowest common denominator
> in the tree, in this case
>
> class ConcreteClient extends AbstractClient {
>  function doStuff(AbstractServer $o) {}
> }
>
> your feedback appreciated,
>
> -nathan
>


It was discussed recently:

http://marc.info/?l=php-internals&m=128220433328115&w=2

Tyrael

---

## #49883 — Ionut G. Stan — 2010-10-07T08:02:55+00:00

URL: https://externals.io/message/49881#49883 · In reply to: #49881

> Hi,
>
> Probly rehashing an old conversation here, but I'm wondering why the
> following isn't supported
>
> <?php
> abstract class AbstractServer {}
> class ConcreteServer extends AbstractServer {}
>
> abstract class AbstractClient {
>    abstract function doStuff(AbstractServer $o);
> }
>
> class ConcreteClient extends AbstractClient {
>    function doStuff(ConcreteServer $o) {}
> }
> ?>

Here's the problem:

     class ConcreteServer2 extends AbstractServer
     {}

Now, ConcreteClient can't receive an instance of ConcreteServer2 as an 
argument, although the initial hint, AbstractServer would have allowed it.

-- 
Ionuț G. Stan  |  http://igstan.ro

---

## #49887 — Richard Lynch — 2010-10-08T02:07:09+00:00

URL: https://externals.io/message/49881#49887 · In reply to: #49881

> <?php
> abstract class AbstractServer {}
> class ConcreteServer extends AbstractServer {}
>
> abstract class AbstractClient {
>   abstract function doStuff(AbstractServer $o);
> }
>
> class ConcreteClient extends AbstractClient {
>   function doStuff(ConcreteServer $o) {}
> }
> ?>
>
> This results in a fatal
> Fatal error: Declaration of ConcreteClient::doStuff() must be
> compatible
> with that of AbstractClient::doStuff() in
> /Users/quickshiftin/gitRepos/timberline/php-api-v15-client/testOverride.php
> on line 11
>
> I was reading a few posts from way back when
>
> http://marc.info/?t=107774904800001&r=1&w=2
>
> yet still find myself wondering.  I think it can be said here that if
> there's a contract defined by AbstractClient::doStuff, that same
> contract is
> honored by ConcreteClient::doStuff.  I also think changing the
> language to
> support this notion wouldn't raise BC issues for the most part (at
> all?)
> since at the moment you're forced to move to the lowest common
> denominator
> in the tree, in this case
>
> class ConcreteClient extends AbstractClient {
>   function doStuff(AbstractServer $o) {}
> }
>
> your feedback appreciated,

I can see why you think it "should" work, but have you considered all
the possible combinations of children/parent abstract/concrete
classes, and what happens when you do:

class QuickMixClient extends ConcreteClient {
  function doStuff(AbstractServer $o) {}
}

class QuickMixServer extends AbstractServer {
}

$quickie = new QuickMixServer;
$client = new QuickMixCilent;
$client->doStuff($quickie);

Kosher?  Or not?

It's kosher for the QuickMix doStuff, but does not satisfy the
ConcreteServer requirement of ConcreteClient.

So does PHP need to examine every method on every class, and then
complain at compile time?...

That sounds painful to me...
.
.
.



-- 
brain cancer update:
http://richardlynch.blogspot.com/search/label/brain%20tumor
Donate:
https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FS9NLTNEEKWBE
