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

Reply via email to