"void Function(int)" 不是 "void Function(dynamic)" 的有效覆盖重写。

4
class Parent<T> {
  void method(T t) {}
}

class Child extends Parent {
  @override
  void method(int i) {} // error: mentioned_below

  void takesDynamic(dynamic d) {
    takesType(d); // no error
  }

  void takesType(int i) {
    takesDynamic(i); // no error
  }
}

错误:

void Function(int) 不是 void Function(dynamic) 的有效覆盖

当我可以轻松地将 int 参数传递给使用 dynamic 的方法,反之亦然,为什么重写方法时会出现此错误。


PS:

我不想使用 extends Parent<int> 解决问题,我想知道为什么在重写方法与调用常规方法时会有不同的处理方式。

1个回答

10

void Function(int x)通常不是void Function(dynamic x)的有效覆盖,因为int版本不能替换dynamic版本。

void Function(dynamic)(即Parent<dynamic>.method的类型)允许的输入是什么?任何东西

void Function(int)(即Child.method的类型)允许的输入是什么?只有int

因此,这样的覆盖可能会违反Parent<dynamic>接口的契约。(例如,如果您有一个Child实例并将其传递给期望Parent<dynamic>的某些内容,然后在其上调用method('not an int')怎么办?)

(请注意,这不是特定于方法覆盖的。 通常情况下,接受较窄类型的函数不能用于期望较宽类型的函数的位置,即使较窄类型派生自较宽类型。)

Dart 允许您使用 covariant 关键字 来抑制静态类型错误并明确允许覆盖,但请注意,这样做不一定是类型安全的,您需要负责确保在运行时不会出现类型错误。
进一步阅读:来自维基百科的协变和逆变(计算机科学)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接