Can you have second order generics in Dart?
abstract class Foo<T, ContainerType<T>> {}
class FooList<T> extends Foo<T, List<T>> {}
Yes, and some more characters to make it 30
I think what you want is something like:
abstract class Foo<T, C extends Iterable<T>> {}
class FooList<T> extends Foo<T, List<T>> {}
(If not, try refining the question and say what you want to achieve).
Related
I have a base package that defines A:
class A {}
Then a package that defines this:
mixin Aa on A {}
mixin Ab on A {}
abstract class First extends A with Aa, Ab{}
and another that defines this:
mixin Ax on A {}
mixin Ay on A {}
abstract class Last extends A with Ax, Ay {}
Then the package that gets that together with the problem
abstract class Clazz extends A with First, Last {} // <- Can't have those mixins bc they don't extend from Object
Question: Is there a way of grouping mixins or are we forced to implement them one by one?
You are forced to implement the one-by-one.
There is currently no way to combine mixins into units that can be applied as one.
Hopefully there will eventually be something like that. It's one the language team's radar (https://github.com/dart-lang/language/issues/540), but so is a lot of other enhancements.
From:
https://medium.com/dartlang/announcing-dart-2-1-improved-performance-usability-9f55fca6f31a
Under Mixins:
mixin SomeClass<T extends SomeOtherClass>
on State<T>
implements ThirdClass
What is "on"?
This mixin can only be applied to classes that extend or implement State<T> which is effectively the state of a stateful widget.
Figuratively speaking on is the extends for mixins.
mixin A on B
is like
class A extends B
To choose which one to use is like to choose between composition or inheritance. More on that composition vs inheritance thing.
What is the difference?
class ExtraPowers{}
class ClassPowers extends ExtraPowers{}
mixin MixinPowers on ExtraPowers{}
Let's say our main character is class "C" and we want to give it some extra capabilities and powers. We can do that in two ways:
// e.g. inheritance
class C extends ClassPowers{}
or
// e.g. composition
class C with ExtraPowers, MixinPowers{}
So if we choose to extend we may need to comply to some requirements. And we can do that by passing arguments to super.
If we choose to gain powers by using with can't use super to pass requirements. The requirements are satisfied by having the same extra powers as our mixin (nothing is left hidden e.g composition) and that on keyword tells us what extra powers our mixin has. So in order to get powers from MixinPowers we first must get ExtraPowers.
class C with ExtraPowers, MixinPowers{}
In conclusion on just like extends gives access to members of another object but on is for mixins extends for classes. The difference is when you use mixin you must implement the objects after the on keyword.
More info
On a flutter example project I stumbled upon those lines:
abstract class BlocEvent extends Object {}
abstract class BlocState extends Object {}
abstract class BlocEventStateBase<BlocEvent, BlocState> {}
Is this a class based on map? or maybe class with two types?
What is the meaning of <BlocEvent, BlocState>?
It's a generic type declaration, but as #yelliver pointed out, the example you posted is not correct, since BlocEvent and BlocState inside <> are just interpreted as generic type identifiers (unrelated to the classes with the same name).
This would make sense:
abstract class BlocEvent extends Object {}
abstract class BlocState extends Object {}
abstract class BlocEventStateBase<T extends BlocEvent, S extends BlocState> {}
Also, note that there are conventions for naming type parameters.
I wonder if there is the possibility to dynamically extend a class, I'm new to Dart and I'm looking for something like this (please forget about the ${whatever} is just for illustration purposes):
class MyClass extends ${otherClass}
and let's say I'm trying to instantiate it from another function:
var myDinamic = new myClass<otherClass>
Hope this makes sense and thanks in advance!
In short: No.
Dart requires all classes to have a single superclass. What you are asking for is having a single class that changes its superclass per instance. That's not really a single class - it's impossible to say which members that class has because it is really a different class for choice of superclass.
That a class extends another class can only be defined statically but not at runtime. The closest to that is probably configuring types with generic type arguments.
See also
- https://www.dartlang.org/docs/dart-up-and-running/ch02.html#generics
- http://blog.sethladd.com/2012/01/generics-in-dart-or-why-javascript.html
abstract class SomeInterface {}
class A implements SomeInterface {}
class B implements SomeInterface {}
class C<T extends SomeInterface> {
T doSomething(T arg) { return arg; }
}
main() {
new C<A>();
new C<B>();
// does NOT work
// var t = A;
// new C<t>();
}
but type arguments also need to defined statically. You can't use a variable as generic type argument.
i want to do something like the following so bad
abstract class A{}
abstract class B extends A{}
abstract class C extends A{}
abstract class D extends B with C{} //C cannot be used as a mixin because it extends a class other than object
is there any solution other than copying the content of C in D?
the real names of my classes, to give you an idea of what i am trying to do
//A Observable
//B DynamicObservable
//C ObservableWithValidationErrors
//D DynamicObservableWithValidationErrors
There are some restrictions on the class you can use as mixin (See Mixins in Dart - Syntax and semantics).
However, in this proposal, a mixin may only be extracted from a class that obeys the following restrictions:
The class has no declared constructors.
The class’ superclass is Object.
The class contains no super calls.
Those restrictions may be removed in the future.
The semantics are deliberately restricted in several ways, so as to reduce disruption to our existing implementations, while allowing future evolution toward a full-fledged mixin implementation. This restricted version already provides considerable value.
In some circumstances it might be possible to restructure your class to use multiple mixins instead:
abstract class Observable{}
abstract class Dynamic{}
abstract class ValidationErrors{}
abstract class DynamicObservable extends Observable with Dynamic{}
abstract class ObservableWithValidationErrors extends Observable with ValidationErrors{}
abstract class DynamicObservableWithValidationErrors extends Observable with Dynamic, ValidationErrors{}
Of course, if Dynamic or ValidationErrors cannot be isolated this way, and rely on inheriting from Observable, this will not be possible.