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.
Related
Say I have the abstract class A
abstract class A {
A.someConstructor(Foo foo);
}
and all subclasses of A should then implement such constructor:
class B extends A {
#override
B.someConstructor(Foo foo) {
// ...
}
}
So basically what I want is some kind of abstract constructors.
Is there any way of achieving this (of course the above code does not work) or do I need a normal abstract method which then creates the object and sets its properties?
EDIT: Ok so it looks like the only way to create at least a similar behaviour would be something like this:
abstract class A {
A.someConstructor(Object foo);
}
class B extends A {
B.someConstructor(Object foo) : super.someConstructor(foo) {
// ...
}
}
This isn't exactly useful, and after some thinking about my problem I realized that in fact my original goal itself is not really neccessary, so this questions is now answered.
You want to enforce a pattern on the constructors of subclasses. The Dart language has no support for doing that.
Dart has types and interfaces which can be used to restrict values and class instance members.
If a class implements an interface, then its instance members must satisfy the signatures declared by the super-interface. This restricts instance members.
If a variable has a type, for example a function type, then you can only assign values of that type to it. This restricts values. Because a class is a subtype of its interfaces, the subclass restriction means that class typed variables can be used safely (the subtype can be used as its supertype because it has a compatible interface).
There is no way to restrict static members or constructors of classes, or members of libraries, because there is no way to abstract over them. You always have to refer directly to them by their precise name, so there is no need for them to match a particular pattern.
(Which may explain why you found the goal not necessary too).
In this situation, your subclasses must call the A.someConstructor constructor, but they are free to choose the signature of their own constructors. They can do:
class B extends A {
B.someConstructor(Object foo) : super.someConstructor(foo);
}
// or
class C extends A {
C.differentName(Object foo) : super.someConstructor(foo);
}
// or even
class D extends A {
D() : super.someConstructor(new Object());
}
Constructors aren’t inherited
Subclasses don’t inherit constructors from their superclass. A
subclass that declares no constructors has only the default (no
argument, no name) constructor.
Source
I've been trying to implement a state management project for my design patterns course. I have implemented the singleton because I know that's essential for keeping state of a class. What I would like to do is: Create a general class, so that others could use it in their projects. How do I do that? My code so far:
class StateManager{
static final StateManager _instance = StateManager._singleton();
StateManager._singleton();
factory StateManager(){
return _instance;
}
}
My other solution to try and make it general:
class AppProvider extends StateManager<AppProvider>{
int i = 10;
String data = "adas";
}
class StateManager<T extends AppProvider>{
static final StateManager _instance = StateManager._singleton();
StateManager._singleton();
factory StateManager(){
return _instance;
}
}
I want the AppProvider class to be the client class, and I want the StateManager to automatically handle the fact that AppProvider should be a singleton, and maintain the state of AppProvider.. I really don't know how to do that.
Forcing a class to be a singleton through inheritance alone is not going to work. That's not something that the language supports. Constructors are not inherited, neither are static members, and you need those to access the singleton.
In order to be able to create an instance of a class at all, the class needs a generative constructor.
That generative constructor will create a new instance every time it's invoked, because that's what generative constructors do.
For a subclass to be able to extend a class, the superclass must have an accessible generative constructor too, but at least the superclass can be made abstract.
In order to force a class to be a singleton (if you really want that, because a singleton is really something of an anti-pattern; it makes the class act like it's just a bunch of global variables, and that makes testing harder), each such class needs to have a public static way to access or create the instance, and a private generative constructor.
So, basically, your first approach does what is needed, and since the constructors are not inherited, you need to do that for every singleton class, and there is nothing useful to inherit.
So, there is nothing you can do with inheritance to make singleton-ness be inherited, and you can't even help because everything a singleton needs is static.
A different approach is to make the state classes entirely private, so you don't have to worry about someone else creating instances, and give them a constant generative constructor each, and then only refer to them using const _ThisState() or const _ThatState().
This puts the responsibility on the user (you!) to only create one instance of each state object, but it also gives a very easy way to do that, because const _ThisState() will provide the same instance every time.
Or use the enum pattern, and have:
abstract class State {
static const State thisState = const _ThisState();
static const State thatState = const _ThatState();
const State._();
void handle(Context context, Object argument);
}
class _ThisState implements State {
const _ThisState();
void handle(Context context, Object argument) { ... }
}
class _ThatState implements State {
const _ThatState();
void handle(Context context, Object argument) { ... }
}
and then just refer to the state instances as State.thisState. I find that more readable than creating instances of seemingly unrelated classes.
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 have abstracted a bunch of code to behaviors, and now when i do:
class B extends A with behave {
B():super(){}
}
class A extends PolymerElement{
A(){}
}
abstract class behave {
test(){ print("Test"); }
}
So what I have been trying to do is create a workflow without having to append references to this new function test
As of right now, if you implement test in A or B, it will override the behavior I had created. But I was hoping to append more to it, something similar to:
class B extends A with behave {
B():super(){}
test():super.test(){}
}
and this would do something like call the parent test. Now when looking this, i would say, this would make sense if the behavior was in the parent. So lets test that out.
abstract class behave { ... }
class A extends behave { ... }
class B extends A {
test(){
super.test();
}
}
This would work and execute what I was wanting to do... Why cant i reference it in the instantiation? test():super.test(){ ... } It seems that doing as just stated will error as a constructor error.
Now what if we put it back to my original design, as behave being with B
abstract class behave { ... }
class A { ... }
class B extends A with behave {
test(){
super.test();
print("Foo");
}
}
now here it seems to work as expected, requiring us to create a super reference to this behavior.
Is there an idea of using : for referencing a parent function call, or is this only ever used for constructors? I would say, yes it is only used for constructors for now, but why not append additional functionality. If i wanted to create a series of functions in the behavior which mimic the child implementation, I should either run super.test() either at the top of bottom of the function depending on the order required to function?
Is there something I am missing in dart when reading the docs, or is this how it is suppose to work for the time being?
I doubt that foo() : super.foo() syntax will be added to the language. The : for constructor initializers is useful because the initializers can be analyzed at compile time, which make it simple to verify that final fields are set for instance. The : syntax in a function would just be syntactic sugar for putting that function call at the beginning of the function, which doesn't seem to add much value.
By the way, you can add #mustCallSuper to your the test() function. This will add a check to the linter that all methods that override test() must call super.test().
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.