Benefits of an abstract class with a factory constructor?

In your example the benefits are limited but in more complex situations the benefits become more clear.

A factory constructor allows you more control about what the constructor returns. It can return an instance of a subclass or an already existing (cached) instance.

It can return different concrete implementations based on a constructor parameter:

abstract class WidgetService {
  WidgetService _cached;

  factory WidgetService(String type) {
    switch (type) {
      case 'a':
        return ConcreteWidgetServiceA();
      case 'b':
        return ConcreteWidgetServiceB();
      default:
        return _cached ??= DummyWidgetServiceA();
    }
  }

  Widget getWidget();

  void saveWidget(Widget widget);
}

Your example seems to be a preparation to be extended eventually to such a more flexible approach.


In Dart, all classes are also automatically interfaces. There's nothing strange about creating a instance of - 'newing up' - an 'interface', because it's actually just creating an instance of a class.

The purpose of some abstract classes is specifically to define an interface, but they have factory constructors that return a 'default implementation' of themselves.

For instance:

void main() {
  var v = new Map();
  print(v.runtimeType);
}

prints: _InternalLinkedHashMap - the (current) default implementation of Map.

Core library users can create and using instances of Map without knowing or caring about the implementation they actually get. The library authors may change the implementation without breaking anyone's code.

Of course, other classes may implement Map also.

With respect to your code sample, WidgetService _service = new WidgetService(); does not produce an analyzer warning. See this example on DartPad (Note I fixed a couple of errors in your sample).

I was initially confused by:

factory WidgetService() = ConcreteWidgetService;

instead of:

factory WidgetService() => new ConcreteWidgetService();

but it seems to work.