Dart模板class继承模板参数

Dart template class inheriting from the template parameter

我想在 Dart 中执行此操作:

abstract class A
{
  int f();
}

class A1 extends A
{
  @override
  int f() => 1515;
}

class A2 extends A
{
  @override
  int f() => 1789;
}

class X<T extends A> extends T
{
  int x() => f();
}

void main()
{
  X<A1> x1 = X<A1>();
  X<A2> x2 = X<A2>();
  
  print( x1.x() ); // Should print 1515;
  print( x2.x() ); // Should print 1789;
}

关键行是定义模板的那一行class X:编译器抱怨因为 X 继承了模板参数(它扩展了 A,所以它可以知道它是一个 class) .

我可能承认我对这门语言的推动有点远(我的 C++ 背景...)但是有没有办法在 Dart 中执行此操作?

附录

我试过这个:

abstract class A
{
  A();
  
  int f();
}

class A1 extends A
{
  A1();

  @override
  int f() => 1515;
}

class A2 extends A
{
  A2();

  @override
  int f()=>1789;
}

class X<T extends A> {
  late T t;
  
  X(){
    t = T();
  }
  int x() => t.f();
}

void main()
{
  X<A1> x1 = X<A1>();
  X<A2> x2 = X<A2>();
  
  print( x1.x() );
  print( x2.x() );
}

但是编译器现在在 t = T();...

线上抱怨

'T' isn't a function. Try correcting the name to match an existing function, or to define a method or function name 'T'.

即使没有模板也是一个解决方案,但概念与我正在寻找的不符。

  • 在上面的问题中,X和x本身就是两种不同的服务。
  • 在下面的解决方案中,X 是使用 A1 或 A2 作为子服务提供者的服务。

瞧:

abstract class A
{
  A();
  
  int f();
}

class A1 extends A
{
  A1();

  @override
  int f() => 1515;
}

class A2 extends A
{
  A2();

  @override
  int f()=>1789;
}

class X {
  late A t;
  
  X(A x){
    t = x;
  }
  int x() => t.f();
}

void main()
{
  X x1 = X(A1());
  X x2 = X(A2());
  
  print( x1.x() ); // Indeed prints 1515
  print( x2.x() ); // Indeed prints 1789
}

Dart 有 generics,它与 C++ templates 相似但不同。 C++ 模板更类似于在编译时替换模板参数的宏,它会为每个模板参数组合生成单独的模板编译版本 class。 Dart 泛型是不同的,而是像 Java's:泛型有一个编译版本 class.

因此,您不能像使用 C++ 那样将 duck-typing 与 T 一起使用,也不能调用 T 构造函数或 static 方法。

您可以做的是提供一个构造 T 的回调,例如:

class X<T extends A> {
  T t;
  
  X(T Function() makeT) : t = makeT();

  int x() => t.f();
}

void main()
{
  X<A1> x1 = X(A1.new);
  X<A2> x2 = X(A2.new);

  ...
}

(我还使 X.t 不再是 late(如果您通过构造函数的初始化列表初始化它,则 late 是不必要的)并在调用 [= 时删除了显式类型参数18=] 构造函数(它们现在可以从参数中推断出来)。)