On 4/7/2016 8:43 PM, Fleshgrinder wrote:
> On 4/7/2016 8:05 PM, Rowan Collins wrote:
>> Meanwhile, it might be worth checking the list archives for previous
>> discussions of package visibility; I know it has come up a couple of
>> times recently, in various forms, so it would be good not to repeat the
>> same points again and again.
>>
> 
> I check what I can dig up. :)
> 

Here we go:

# 2007-12: Namespace access modifiers
http://marc.info/?t=119750415000002

# 2009-09: New access modifier
http://marc.info/?l=php-internals&m=125341032112627

Some nice keyword suggestions in this one:
- group
- trusted
- party

# 2011-03: Class Access Modifiers
http://marc.info/?t=129917302700001

# 2013-02: I would like to write an RFC for the addition of an internal
keyword
http://marc.info/?t=136194893000003

# 2014-12: Package private class
http://marc.info/?t=141929489300003

# 2015-11: Internal methods proposal
http://marc.info/?t=144836744000001

I am sure that I overlooked something since the search turned up a lot
of stuff. However, the above list already illustrates that such a
feature is often requested and useful. This is further illustrated by
other languages providing similar functionality.

There were various questions raised in the threads above that I would
like and try to answer here.

> Can child classes redeclare visibility or override it.

Yes, every class in an inheritance change can open up the visibility as
is already the case for methods in PHP. The reason for that is simple:

    namespace Process\Pipes {

        public interface Pipes {}

        abstract private class AbstractPipes implements Pipes {}

        protected final class UnixPipes extends AbstractPipes {}

        protected final class WinPipes extends AbstractPipes {}

    }

The UnixPipes and WinPipes classes are useless if they cannot open up
the visibility because they cannot be instantiated from nowhere.

> It would still be possible to get an instance of a private class from
> the outside, e.g.:
>
>     namespace Internals {
>         private class Foo {}
>         public class Bar {}
>             public function getFoo() {
>                 return new Foo();
>             }
>         }
>    }

Yes and this is intentional. The class visibility modifiers only
restrict the creation of such objects and not the interaction with them
at runtime. Otherwise it would be impossible to implement a public
interface in a private class that is being returned to the client.

    public interface Entities extends \IteratorAggregate {}

    public interface EntityManager extends Entities {}

    private class InMemoryEntities implements EntityManager {}
    private class FilesystemEntities implements EntityManager {}
    private class MySqlEntities implements EntityManager {}
    private class PdoEntities implements EntityManager {}

    switch (ENV) {
        case PROD:
            $entities = new MySqlEntities;
            break;

        case TEST:
            $entities = new InMemoryEntities;
            break;
    }

    $dic->addService('entities', $entities, [
        'alias' => 'entitye_manager',
    ]);

This is not /good code/ or anything but should illustrate the usefulness
of it. In other words:

It supports the I in SOLID. :)

https://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29

-- 
Richard "Fleshgrinder" Fussenegger

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to