Static classes in PHP via abstract keyword?

2019-03-09 02:12发布

According to the PHP manual, a class like this:

abstract class Example {}

cannot be instantiated. If I need a class without instance, e.g. for a registry pattern:

class Registry {}
// and later:
echo Registry::$someValue;

would it be considered good style to simply declare the class as abstract? If not, what are the advantages of hiding the constructor as protected method compared to an abstract class?

Rationale for asking: As far as I see it, it could a bit of feature abuse, since the manual refers to abstract classes more as like blueprints for later classes with instantiation possibility.

Update: First of all, thanks for all the answers! But many answers sound quite alike: 'You cannot instantiate an abstract class, but for a registry, why not using a singleton pattern?'

Unfortunately, that was more or less exactly a repeat of my question. What is the advantage of using a singleton pattern (a.k.a. hiding __construct()) compared to just declaring it abstract and not having to worry about that? (Like, e.g., it is a strong connotation between developers, that abstract classes are not actually used or so.)

10条回答
来,给爷笑一个
2楼-- · 2019-03-09 03:02

If your class is not meant to define some super-type, it should not be declared as abstract, I'd say.

In your case, I would rather go with a class :

  • That defines __construct and __clone as private methods
    • so the class cannot be instanciated from outside
  • And, this way, your class could create an instance of itself


Now, why use a Singleton, and not only static methods ? I suppose that, at least a couple of reasons can be valid :

  • Using a singleton means using an instance of the class ; makes it easier to transform a non-singleton class to a singleton one : only have to make __construct and __clone private, and add some getInstance method.
  • Using a singleton also means you have access to everything you can use with a normal instance : $this, properties, ...
  • Oh, a third one (not sure about that, but might have its importance) : with PHP < 5.3, you have less possibilities with static methods/data :
    • __callStatic has only been introduced in PHP 5.3
    • There is no __getStatic, __setStatic, ...
    • Same for a couple of other Magic methods !
  • Late Static Binding has only been added with PHP 5.3 ; and not having it often makes it harder, when working with static methods/classes ; especially when using inheritance.


This being said, yes, some code like this :

abstract class MyClass {
    protected static $data;
    public static function setA($a) {
        self::$data['a'] = $a;
    }
    public static function getA() {
        return self::$data['a'];
    }
}

MyClass::setA(20);
var_dump(MyClass::getA());

Will work... But it doesn't feel quite natural... and this is a very simple example (see what I said earlier with Late Static Binding, and magic methods).

查看更多
Juvenile、少年°
3楼-- · 2019-03-09 03:03

abstract really is meant to indicate a "blueprint", as you call it, for class inheritance.

Registries generally follow a singleton pattern, which means they it would instantiate itself in a private variable. Defining it as abstract would prevent this from working.

查看更多
\"骚年 ilove
4楼-- · 2019-03-09 03:08

There are patterns in OO that are common and well-recognized. Using abstract in an unconventional way may cause confusion (sorry, my some examples are in Java instead of PHP):

  • abstract class - a class meant to conceptualize a common ancestor, but of which actual instances are not meant to exist (e.g. shape is an abstract superclass for rectangle and triangle).
    Commonly implemented by:
    • use abstract modifier on class to prevent direct instantiation, but allow deriving from the class
  • utility class - a class that does not represent an object in the solution space, but rather is a collection of useful static operations/methods, e.g. Math class in Java.
    Commonly implemented by:
    • make class non-derivable, e.g. Java uses the final modifier on class, and
    • prevent direct instantiation - provide no constructors and hide or disable any implicit or default constructors (and copy constructors)
  • singleton class - a class that does represent an object in the solution space, but whose instantiation is controlled or limited, often to insure there is only one instance.
    Commonly implemented by:
    • make class non-derivable, e.g. Java uses the final modifier on class, and
    • prevent direct instantiation - provide no constructors and hide or disable any implicit or default constructors (and copy constructors), and
    • provide a specific means to acquire an instance - a static method (often getInstance()) that returns the only instance or one of the limited number of instances
查看更多
祖国的老花朵
5楼-- · 2019-03-09 03:14

Setting a class to abstract that only defines static properties/methods won't have a real effect. You can extend the class, instantiate it, and call a method on it and it would change the static class properties. Obviously very confusing.

Abstract is also misleading. Abstract is ment to define an class that implements some functionality, but needs more behaviour (added via inheritance) to function properly. On top of that it's usually a feature that shouldn't be used with static at all. You are practically inviting programmers to use it wrong.

Short answer: A private constructor would be more expressive and fail safe.

查看更多
登录 后发表回答