From here:
bool shouldReclip(covariant CustomClipper<T> oldClipper);
AFAIK, the keyword covariant is used when you override a method explicitly telling the analyzer that you're going to provide it a valid type. But in CustomClipper class, there's no such override, so why covariant is used?
You can mark a parameter as covariant in the superclass, then subclasses automatically get their parameters marked covariant too.
If the class is intended to be extended, this can be a service (and documentation) for the subclass authors so they know that the parameter is supposed to be used covariantly.
If you look at this subclass, you can see that they declare:
#override
bool shouldReclip(_DecorationClipper oldClipper) {...}
which is covariantly overriding the parameter type CustomClipper<Path> with _DeclarationClipper (which implements CustomClipper<Path>), and they don't have to write covariant here because the superclass declared it for them.
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
A common question, specifically since Dart 2, is if it is possible to require some or all generic type arguments on some or all types - for example List<int> instead of List or MyType<Foo> instead of MyType.
It's not always clear what the intention is though - i.e. is this a matter of style (you/your team likes to see the types), to prevent bugs (omitting type arguments seems to cause more bugs for you/your team), or as a matter of contract (your library expects a type argument).
For example, on dart-misc, a user writes:
Basically, if I have this:
abstract class Mixin<T> {}
I don't have to specify the type:
// Works class Cls extends Object with Mixin<int> {} // ...also works
class Cls extends Object with Mixin {}
Is there some way to make the second one not allowed?
Strictly speaking, yes, and no.
If you want to enforce that type arguments are always used in your own projects (instead of relying on type inference or defaults), you can use optional linter rules such as always_specify_types. Do note this rule violates the official Dart style guide's recommendation of AVOID redundant type arguments on generic invocations in many cases.
If you want to enforce that generic type arguments are always used when the default would be confusing - such as List implicitly meaning List<dynamic>, no such lint exists yet - though we plan on adding this as a mode of the analyzer: https://github.com/dart-lang/sdk/issues/33119.
Both of the above recommendations will help yourself, but if you are creating a library for others to use, you might be asking if you can require a type argument to use your class. For example, from above:
abstract class Mixin<T> {}
abstract class Class extends Object with Mixin {}
The first thing you could do is add a default bounds to T:
// If T is omitted/not inferred, it defaults to num, not dynamic.
abstract class Mixin<T extends num> {}
If you want to allow anything but want to make it difficult to use your class/mixin when T is dynamic you could choose a different default bound, for example Object, or even better I recommend void:
In practice, I use void to mean “anything and I don’t care about the elements”
abstract class Mixin<T extends void> {
T value;
}
class Class extends Mixin {}
void main() {
var c = Class();
// Compile-time error: 'oops' isn't defined for the class 'void'.
c.value.oops();
}
(You could also use Object for this purpose)
If this is a class under your control, you could add an assertion that prevents the class from being used in a way you don't support or expect. For example:
class AlwaysSpecifyType<T> {
AlwaysSpecifyType() {
assert(T != dynamic);
}
}
Finally, you could write a custom lint or tool to disallow certain generic type arguments from being omitted, but that is likely the most amount of work, and if any of the previous approaches work for you, I'd strongly recommend those!
I wanted to write a simple behavior in Dart to be used by a custom element.
#behavior
abstract class AlignmentBehavior implements PolymerBase {
#Property()
bool alignTop = false;
// more properties ...
ready() {
updateAlignment();
}
#reflectable
updateAlignment([_,__]) {
// reference to the element the Behavior is attached to.
// 1) Is that the correct way?
var ele = Polymer.dom(root);
// We need to inherit from PolymerBase to access set(...)
// 2) Is that the correct way?
set('alignTop', aTop);
// .. to more stuff
}
}
My first two questions are already written in the code. How do I access the element the behavior is attached to? What's the proper way of doing this? I currently use Polymer.dom(root) but I don't know if that even works since I have some runtime errors which I am going to explain later in this post. What is the official way of accessing the underlying element? Is it using the JsObject? Is it calling a Behavior function from the parent PolymerElement and pass this, or should you not access it at all?
Another question is whether I have to inherit from PolymerBase or not. The Behavior example at the Github wiki doesn't do so, but in order to access methods such as set to modify a #Property I have to inherit from it. What's the proper way of doing so?
My last two questions are about errors I get. One error asks me to implement getters and setters for my properties, such as adding a getter and setter for alignTop.
And last but not least, I cannot invoke updateAlignment() from my custom element. It says Class 'MainApp' has no instance method 'updateAlignment'.
1)
var ele = Polymer.dom(root);
If you want to access the DOM of the element, this fine.
Just root gives you the same AFAIK.
If you want to access the elements class instance, there is nothing to do. It's this but that is implicit in Dart anyway.
You can only access what is known in the mixin. To make "things" known to the mixin you can create an interface class.
abstract class MyComponentInterface {
void someFunction();
int someField;
String get someValue;
set someValue(String value);
...
}
Then implement the interface in the mixin and the element class and you have a shared contract.
abstract class AlignmentBehavior implements MyComponentInterface, PolymerBase {
The mixin can now access the members because the implementsMyComponentInterface` claims they will exist and
class MyComponent extends PolymerElement with AlignmentBehavior {
will force you to implement it to fulfill the contract of the mixin.
2) looks fine
3)
Another question is whether I have to inherit from PolymerBase or not.
Is basically the same as 1) Any Polymer element in Dart has to extend PolymerBase. To be able to access the members of PolymerBase from within the mixin it has to implement it as well. This doesn't result in any limitations because the classes that the mixin will be applied to, will fulfill that contract anyway.
If you don't need to access any members provided by PolymerBase there is no need to implement it.
What happens to a procedure when it is declared with the keyword dynamic?
And what is the effect of declaring it with the keyword static?
This question can be answered by reading the documentation.
The dynamic keyword introduces a method that can be overridden polymorphically. Semantically it is interchangeable with virtual, but the is implemented in a different manner. Read about it here: http://docwiki.embarcadero.com/RADStudio/en/Methods#Virtual_and_Dynamic_Methods
To make a method virtual or dynamic, include the virtual or dynamic
directive in its declaration. Virtual and dynamic methods, unlike
static methods, can be overridden in descendent classes. When an
overridden method is called, the actual (run-time) type of the class
or object used in the method call--not the declared type of the
variable--determines which implementation to activate.
To override a method, redeclare it with the override directive. An
override declaration must match the ancestor declaration in the order
and type of its parameters and in its result type (if any).
...
In Delphi for Win32, virtual and dynamic methods are semantically
equivalent. However, they differ in the implementation of method-call
dispatching at run time: virtual methods optimize for speed, while
dynamic methods optimize for code size.
In general, virtual methods are the most efficient way to implement
polymorphic behavior. Dynamic methods are useful when a base class
declares many overridable methods that are inherited by many
descendent classes in an application, but only occasionally
overridden.
Class static methods are like class methods in that they are invoked on the class rather than an instance. The difference between class static and class methods is that class methods are passed a Self pointer that contains the class, and class static methods are not. This means that class methods can be polymorphic and class static methods cannot. Read about it here: http://docwiki.embarcadero.com/RADStudio/en/Methods#Class_Static_Methods
Like class methods, class static methods can be accessed without an object reference. Unlike ordinary class methods, class static methods have no Self parameter at all. They also cannot access any instance members. (They still have access to class fields, class properties, and class methods.) Also unlike class methods, class static methods cannot be declared virtual.
With all due respect, I refer you to this question: How can I search for Delphi documentation?
What can I do to prevent the compiler from throwing the following warning
Missing concrete implementation of setter 'MyClass.field' and getter
'MyClass.field'
on the following code?
import 'package:mock/mock.dart';
class MyClass {
String field;
}
#proxy
class MockMyClass extends Mock implements MyClass{}
Implement noSuchMethod(); When a class has a noSuchMethod() it implements any method. I assume this applies to getter/setter as well because they are just special methods (never tried myself yet though). See also https://www.dartlang.org/articles/emulating-functions/#interactions-with-mirrors-and-nosuchmethod
The warning comes because you have a class that doesn't implement its interface, and which doesn't declare a noSuchMethod method.
It's not sufficient to inherit the method, you have to actually declare it in the class itself.
Just add:
noSuchMethod(Invocation i) => super.noSuchMethod(i);
That should turn off the warning for that class.
About this warning ( Dart Spec ) :
** It is a static warning if a concrete class does not have an implementation for a method in any of its superinterfaces unless it declares its own noSuchMethod method (10.10).
**
So you can create an implementation for getter field in your MockMyClass class.