Jonas Bojesen
Jonas Bojesen

Reputation: 865

How to extend from const constructor

class and const gives a nice possibility to define structured constants. Now I try to extend from one, works ok. Try to use a constant from the inherited class, it works, still I only manage to get through with final instead of const. No big deal in my project, but is it possible to have it const?

class A {
  final String name;
  final int value;
  const A(final String this.name, final this.value);
  static const A ONE = const A('One', 1);
}

class B extends A {

  const B(final String name, final int val) : super(name, val);

  static const B B_ONE = const B('One', 1);//Ok
  static const A A_ONE = A.ONE;//Ok
  static final B BA_ONE = new B(A.ONE.name, A.ONE.value);//Ok
  static const B BA_ONE_CONST = const B(A.ONE);//No B constructor!?!

}

Upvotes: 1

Views: 1445

Answers (1)

lrn
lrn

Reputation: 71623

Your B class indeed does not have a constructor that takes a single A instance. You haven't declared one, and you can't do it directly without a little workaround.

The problem is that B extends A, it doesn't just contain an A instance. So, if you want to start with an A instance (like A.ONE) and create a B instance from it, where B extends A and has its own name and value fields, you'll have to extract the name and value from the A to create the new object ... and you can't do property extraction in a const expression. So, that's a no-go.

What you can do is to have a different implementation of B that gets its values directly from an A instance, and then create a constant from that:

class B extends A {
  const B(String name, int value) : super(name, value);
  const factory B.fromA(A instance) = _SecretB;
  ...
  static const B BA_ONE_CONST = const B.fromA(A.ONE);
}
class _SecretB implements B {
  final A _instance;
  const _SecretB(this._instance);
  String get name => _instance.name;
  int get value => _instance.value;
}

If you are the only one using the B.fromA constructor, you could just remove it and call the _SecretB constructor directly. If you want to expose it to other clients of your class, you can make it a const factory constructor like here.

Upvotes: 2

Related Questions