What is the different between <class> with <class> and <class> with <mixin> ?
I have a example:
class Run {
void run(String name) {
print('$name run');
}
}
class People with Run {}
class Dog with Run {}
void main() {
final people = People();
final dog = Dog();
people.run('${people.runtimeType}');
dog.run('${dog.runtimeType}');
}
I cannot seen different after i had changed class Run to mixin Run
mixin is used to specify that the class is only to be used as a mixin.
You can mixin plain classes or abstract classes, but they can be subclassed and the former can be instanced. If you want to prevent that you should use a mixin. I believe it should be more common to define mixins purposefully.
mixin rules are different from mixing in other classes.
Read more about here.
Related
I'm new to Dart, and I want to receive only widgets that inherit a specific interface.
In other languages, a class that satisfies two interfaces could be passed to a function.
But in Dart, I can't find a similar function or Generic even if I search, so I'm asking a question.
class TypeClassA {
}
mixin TypeMixInA {
}
class TypeClassB extends TypeClassA with TypeMixInA {
}
class TypeClassC extends TypeClassA with TypeMixInA {
}
void functionA(TypeClassA & TypeMixInA param) { // TypeClassA & TypeMixInA is possible?
}
void main() {
functionA(TypeClassB());
functionA(TypeClassC());
}
Is there a way to receive two interface (two mixins or two classes, etc.) like functionA in the example above?
No, it's not possible.
If TypeMixInA is only ever mixed-in on top of TypeClassA, then you can add implements TypeClassA on TypeMixInA and just use TypeMixInA as the argument type.
If the two are used independently, that won't fly.
Then you can introduce abstract class TypeClassAWithMixInA implements TypeMixInA, TypeClassA {} and make both TypeClassB and TypeClassC implement TypeClassAWithMixInA.
If you're not the author of TypeClassB or TypeClassC, that also won't work.
At that point, there is nothing you can do in the static type system to request only instances of classes that implement two separate interfaces.
The Dart type system does not have intersection types, which is what that would be.
You have to accept one of the types, then dynamically check that it also implements the other type, and throw at run-time if it doesn't.
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 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.
Could somebody please write some formal definition of keyword with in Dart?
In official Dart examples I have only found:
class TaskElement extends LIElement with Polymer, Observable {
But I still can't understand what is it exactly doing.
The with keyword indicates the use of a "mixin". See here.
A mixin refers to the ability to add the capabilities of another class or classes to your own class, without inheriting from those classes. The methods of those classes can now be called on your class, and the code within those classes will execute. Dart does not have multiple inheritance, but the use of mixins allows you to fold in other classes to achieve code reuse while avoiding the issues that multiple inheritance would cause.
I note that you have answered some questions about Java -- in Java terms, you can think of a mixin as an interface that lets you not merely specify that a given class will contain a given method, but also provide the code for that method.
You can think mixin as Interface in Java and like protocol in Swift.Here is the simple example.
mixin Human {
String name;
int age;
void about();
}
class Doctor with Human {
String specialization;
Doctor(String doctorName, int doctorAge, String specialization) {
name = doctorName;
age = doctorAge;
this.specialization = specialization;
}
void about() {
print('$name is $age years old. He is $specialization specialist.');
}
}
void main() {
Doctor doctor = Doctor("Harish Chandra", 54, 'child');
print(doctor.name);
print(doctor.age);
doctor.about();
}
Hope it help to understand.
I'm coming from C#/F#/Haskell so I'm trying to come up with solutions to programming problems I'm used to solving with types.
class A where T : new() in C#, this is mainly so I can do new T() somewhere. This creates a malformed type error in Dart. Is there a reasonably idiomatic way to solve this? Perhaps with factories?
I did some experiments with mixins, in the case of name conflicts for inherited mixin members, the last mixin wins. So for the following:
abstract class mixA { void foo(); }
abstract class mixB { void foo(); }
class C extends Object with mixA, mixB {}
new C().foo();
this would end up calling mixB.foo() whereas
class C extends Object with mixB, mixA {}
would end up calling mixA.foo()
Is there anyway to access the members of the hidden mixins?
Suppose I mix 2 mixins with a field of the same name. Does the subclass instance have 2 fields at runtime (just 1 is inaccessible) or is the object like a dictionary and there is only 1 slot for each name?
1 is not possible. You can't call new on a generic type (or variable for that matter). The most common workaround is to create a closure that allocates the object instead.
The answers for 2 fall out of the fact that Mixins can be seen as super-classes: A extends Object with B, C is basically equivalent to:
class B' extends Object { <copy over code inside B> }
class C' extends B' { <copy over code inside C> }
class D extends C' { ... }
With this in mind:
no. there is no way to access hidden super elements.
yes. you would end up with multiple fields.
Small note: the <copy over code inside X> part is not completely correct since that would change the library-scope. Code from mixin B is conceptually in the library the mixin is declared in.