This question might stem from an inadequate understanding of OOP in Dart, but anyway:
I've been working on a project for which one of my base classes extends ListBase from dart:collections. It is useful in some cases I come across to be able to get the sorted indices of these List-like objects (without actually sorting them).
As a parent class I have something like (heavily simplified):
abstract class A<T> extends ListBase<T> {
List<T> internalList;
List<int> orderedIndices();
...
}
An example descendant is something like:
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]));
}
For example, if an instance of B has [1, 5, 2, 4, 3] as its internalList then orderedIndices will return [0, 2, 4, 3, 1], as expected.
I would like to put the code that implements orderedIndices into class A's definition, however, because it would be identical in any of A's descendants as long as the specified type T is Comparable (i.e. has compareTo defined). I don't know how do this, however, because without knowing the type T, Dart has no way of knowing whether T instances are indeed Comparable and coughs at the compareTo if I try to put the code in A's definition.
Although it would work, I balk at the idea of copy-and-pasting code into descendants of the same class... Is there some way I can tell Dart in my definition of A that T will be a Comparable?
If you want to limit T of A to types that are comparable. That's done by putting a bound on 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]));
...
If not all version of A are comparable, then you can't do that. Then you can make a helper-subclass of A which is:
abstract class ComparableA<T extends Comparable<T>> extends A<T> {
List<int> orderedIndices() => new List<int>.generate( ....
...
}
Then you can do class B extends ComparableA<num> ... to share the comparison behavior when it's possible, and classes extending A directly will need to make their own implementation of the method.
Finally, you could change your specifiation of orderedIndices to:
List<int> orderedIndics(int Function(T, T) compare) {
return List.generate(internalList.length,(i) => i)..sort(
(i, j) => compare(internalList[i], internalList[j]));
}
Then you can choose per invocation how to compare the elements of internalList. If T is Comparable, you can use Comparable.compare as the implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With