On Tue, Feb 21, 2023 at 12:52 PM someniatko <somenia...@gmail.com> wrote: > > 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 >
This reminds me a lot of C#'s "extension methods" which are quite useful. If PHP had something like that, you could do some really nice things: class BMock { public static function bar from A(): int { return 69; } } $a = new A(123); echo $a->bar(); // output: 69 class BReal { public static function bar from A(): int { return $self->foo(); } } // error A::bar() already defined on BMock where `from A` is syntax sugar for `public function bar(A $self) {}` and trying `$a->bar()` is simply syntax sugar for `BMock::bar($a);` -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php