On Nov 27, 2014, at 10:34 PM, Stanislav Malyshev <smalys...@gmail.com> wrote:
>> You are correct. Methods cannot be declared abstract if you have an >> "abstract final". They must also be static. I added these checks together > > To me, it just feels a bit unnatural. So you have abstract class, which > usually has abstract methods. Then you have "abstract final" class which > can not have abstract methods, but instead should have "static" methods. > This just sounds a bit weird to me - adding "final" to description of > the class completely changes all the rules in very unexpected direction. What does it mean to have an abstract static function? Abstract (non-static) functions make sense for abstract classes -- since you cannot instantiate the abstract class, you know that the instantiable subclass that you actually have an instance of must have implemented the method, so it's safe to call. But you *can* call static methods on abstract classes, and so you have no guarantee that the abstract static method exists -- and you need to be very careful with LSB to actually call it correctly anyways. Does this mean that static classes with abstract methods (or abstract static classes, or however this ends up working out syntactically) won't be allowed to have static methods called on them directly? How do you make sure that the methods in them do the right LSB stuff to call the abstract static functions correctly? Inheritance semantics for static classes also get messy when you start dealing with traits. As a quick example, the current proposal only allows static classes to inherit from other static classes... but where do traits fit in here? Only traits with only static methods are allowed to be included? This could lead to some very annoying refactoring scenarios where changing a trait that is used in several places leads to errors with static classes... traits bring up many of the same issues as multiple inheritance, and I think you'll have some of those issues here. All of the above is the crux of the issue of why Hack went with "abstract final" and not anything else. Abstract does not mean "must be subclassed" -- you can have an abstract class with no subclasses and still call static methods on it; this is perfectly meaningful, and is at least how I emulated "abstract final" before Hack got the feature. Abstract means "cannot be instantiated" (and, since it cannot be instantiated, may contain *instance* methods with empty bodies, i.e., abstract methods). Then final means "cannot be subclassed" -- so the two together means you have a class that has no instances itself, and cannot be subclasses, so you can never have an object of that type. The use cases for being able to override such a class are questionable at best, as above. This really is just the combination of two existing class modifiers -- no need to introduce a new "static" modifier. And it leads to lots of interesting issues, as above. Josh Watzman -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php