Search code examples
dartinterface

Dart factory function defined in abstract interface class without default implementation


Is it possible to enforce a class to implement a factory function with a defined function signature? I tried doing it with an abstract interface class, but the problem is, that it requires a default implementation, which means, when implementing the interface in a new class, there is no warning that the default implementation is used (which in this case is just a UnimplementedError).

I found one comment under a post mentioning that this is not possible, but I would like to know for sure and maybe the reasons behind it: Factory method in an abstract class on flutter/dart

Example:

abstract class BulkFetchable {
  Map<String, dynamic> toJson(); //this works nicely
  factory BulkFetchable.fromJson(Map<String, dynamic> json); //this is not allowed
  static String get endpoint; //sidenote, this also doesn't work
}

So the working version would look like this:

abstract class BulkFetchable {
  static String get endpoint => "";
  Map<String, dynamic> toJson();
  factory BulkFetchable.fromJson(Map<String, dynamic> json) {
    throw UnimplementedError();
  }
}

But in that case a class implementing the interface is only forced to implement the method without default implementations.

class A implements BulkFetchable {
  @override
  Map<String, dynamic> toJson() {
    throw UnimplementedError();
  }
  
}

Any other way to achieve this functionality (enforce that a class is implementing the JsonSerializable generated functions)?


Solution

  • No, Dart does not provide a way to enforce that a class implements any static members or constructors. It wouldn't matter anyway, since you can't abstract over classes in a way that would allow you to call those methods.

    A factory is not an instance method, it's not part of the class interface, and it cannot be abstract. It's accessed more like a static member, which also cannot be abstract.

    Interface members can be abstract (at least in abstract classes) because it's possible to provide an implementation for that method in a subclass. When an interface method is called, it will resolve to the actual implementation of the object it's called on, using "late dispatch".

    Static members and constructors are resolved directly. There is nothing else that can provide an implementation, because all references point directly to the static/constructor declaration.