Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 658
ra9r Avatar asked May 23 '19 04:05

ra9r


People also ask

Can abstract class have constructor in Dart?

Like any other classes in Java, abstract classes can have constructors even when they are only called from their concrete subclasses.

Can we define constructor as abstract?

Yes, we can define a parameterized constructor in an abstract class.

Can we call constructor of abstract class?

Yes, an abstract class can have a constructor in Java. You can either explicitly provide a constructor to the abstract class or if you don't, the compiler will add a default constructor of no argument in the abstract class. This is true for all classes and it also applies to an abstract class.


1 Answers

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

like image 109
Ali Türkay Avci Avatar answered Sep 19 '22 06:09

Ali Türkay Avci