Hi again, internals

My marathon of some crazy ideas continues :D, with less crazy one this time.


## Idea

Allow "reimplementing" the non-static public API (that is public
properties and methods, excluding constructor) of a class by other
classes like this:

```php
final class interface A {
    public string $s;

    public function __construct(string $s) { $this->s = $s; }

    public static function fromInt(int $i): self { return new
self((string) $i); }

    public function foo(): int { return 42; }
}

final class B implements A {
    public string $s = 'hello';

    public function foo(): int { return 69; }
}

function usesA(A $param): void {}

usesA(new B); // this works
```


## Explanation

Consider there is a class like this:

```php
final class Service {
    public function __construct(private SomeDependency $dependency) {}
    // ...
}

final class SomeDependency {
    // ...
}
```

We want to write some tests for the Service class, but we don't want
to use a real SomeDependency instance
during tests. A common approach is to either extract an interface
(JUST to make it testable), or to drop the
`final` keyword and allow extending the class.

Both approaches have their flaws:
 - extracting an interface unnecessarily complicates the system, where
only one "real" implementation of an interface is assumed.
 - dropping the `final` keyword allows for the rabbit-hole of
inheritance abuse, like greatly described in this article:
https://front-line-php.com/object-oriented

I believe I came up with a better idea: what if we could leave both
benefits of prohibiting the inheritance abuse and also allow not to
clutter our namespace with excess entities like interfaces? I hereby
suggest to combine the responsibilities of a class and an interface
into one thing like that:

```php
final class interface C {}
final class D implements C {}
```

Now other classes can "implement" this class as well. Introduction of
the new syntax (`class interface`) also solves BC problem - if you
want to forbid your classes to be reimplemented whatsoever, you can
still stick to the `final class` syntax. Although it is also possible
to allow "reimplementing" ANY class, then new syntax is not needed -
but some library writers like Marco Pivetta could be sad about that I
suppose.

Soo..., what do you think? Could this be a valuable addition to the language?

Regards,
Illia / someniatko

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

Reply via email to