简体   繁体   中英

Is it possible to define an abstract named constructor in Dart?

I'm trying to create an abstract class Firestorable which will ensure that subclasses override a named constructor fromMap(Map<String, dynamic> map)

The code looks like this ...

abstract class Firestorable {
  /// Concrete implementations will convert their state into a
  /// Firestore safe [Map<String, dynamic>] representation.
  Map<String, dynamic> toMap();

  /// Concrete implementations will initialize its state
  /// from a [Map] provided by Firestore.
  Firestorable.fromMap(Map<String, dynamic> map);
}

class WeaponRange implements Firestorable {
  int effectiveRange;
  int maximumRange;

  WeaponRange({this.effectiveRange, this.maximumRange});

  @override
  WeaponRange.fromMap(Map<String, dynamic> map) {
    effectiveRange = map['effectiveRange'] ?? 5;
    maximumRange = map['maximumRange'] ?? effectiveRange;
  }

  @override
  Map<String, int> toMap() {
    return {
      'effectiveRange': effectiveRange,
      'maximumRange': maximumRange ?? effectiveRange,
    };
  }
}

I don't get any errors when I do this, however I also don't get a compile error when I leave out the concrete implementation of the fromMap(..) constructor.

For example the following code will compile without any errors:

abstract class Firestorable {
  /// Concrete implementations will conver thier state into a
  /// Firestore safe [Map<String, dynamic>] representation.
  Map<String, dynamic> convertToMap();

  /// Concrete implementations will initialize its state
  /// from a [Map] provided by Firestore.
  Firestorable.fromMap(Map<String, dynamic> map);
}

class WeaponRange implements Firestorable {
  int effectiveRange;
  int maximumRange;

  WeaponRange({this.effectiveRange, this.maximumRange});

//   @override
//   WeaponRange.fromMap(Map<String, dynamic> map) {
//     effectiveRange = map['effectiveRange'] ?? 5;
//     maximumRange = map['maximumRange'] ?? effectiveRange;
//   }

  @override
  Map<String, int> convertToMap() {
    return {
      'effectiveRange': effectiveRange,
      'maximumRange': maximumRange ?? effectiveRange,
    };
  }
}

Am I not able to define an abstract named constructor and have it be a require implementation in a concrete class? If not, what would be the correct way to do this?

As stated in the official guide for the Dart Language constructors aren't inherited so you can't enforce a factory constructor to subclasses. To ensure an implementation it should be part of the class' interface which constructors are not. You can check these related stackoverflow questions for more information:

How to declare factory constructor in abstract classes

How do i guarentee a certain named constructor in dart

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM