在Dart中将类型定义为“可比较”

时间:2018-06-29 15:06:03

标签: oop dart

这个问题可能源于对Dart中对OOP的理解不足,但无论如何:

我一直在从事一个项目,我的一个基础类从ListBase扩展了dart:collections。在某些情况下,能够获得这些类似List的对象的排序索引很有用(实际上没有对其进行排序)。

作为父类,我有类似的东西(大大简化了):

abstract class A<T> extends ListBase<T> {
  List<T> internalList;
  List<int> orderedIndices();

  ...

}

后代示例如下:

class B extends A<num> {

  ...

  @override
  List<int> orderedIndices() => new List<int>.generate(
    internalList.length,(i) => i)..sort(
      (i, j) => internalList[i].compareTo(internalList[j]));
}

例如,如果B的实例具有[1, 5, 2, 4, 3]作为其internalList,则orderedIndices将按预期返回[0, 2, 4, 3, 1]

但是,我想将实现orderedIndices的代码放入类A的定义中,因为只要A的任何后代都相同,指定的类型TComparable(即定义了compareTo)。但是我不知道该怎么做,因为在不知道类型T的情况下,Dart无法知道T实例是否确实是Comparable并在{{1}咳嗽},如果我尝试将代码放入compareTo的定义中。

尽管可以工作,但我不赞成将代码复制粘贴到同一类的后代中。...有什么办法可以使我在A的定义中告诉Dart {{1 }}将是A

1 个答案:

答案 0 :(得分:1)

如果要将T中的A限制为可比较的类型。通过在T上设置界线来完成:

abstract class A<T extends Comparable<T>> extends ListBase<T> {
  ...
  List<int> orderedIndices() => new List<int>.generate(
    internalList.length,(i) => i)..sort(
      (i, j) => internalList[i].compareTo(internalList[j]));
  ...

如果不是A的所有版本都具有可比性,那么您就不能这样做。然后,您可以创建A的辅助子类:

abstract class ComparableA<T extends Comparable<T>> extends A<T> {
   List<int> orderedIndices() => new List<int>.generate( ....
   ...
}

然后,您可以class B extends ComparableA<num> ...共享比较行为,并且直接扩展A的类将需要自己实现该方法。

最后,您可以将orderedIndices的规范更改为:

List<int> orderedIndics(int Function(T, T) compare) {
  return List.generate(internalList.length,(i) => i)..sort(
      (i, j) => compare(internalList[i], internalList[j]));
}

然后,您可以根据每次调用选择如何比较internalList的元素。如果TComparable,则可以使用Comparable.compare作为实现。