Dart. Child class and constructor initializer list - dart

I play with Dart (leaf through Tour of the Dart Language) and I found that I can't use initializer list on child classes. Why?
main() {
var rbt = new Robot.fromJson({'x':21, 'y':21});
}
class Human {
}
class Robot extends Human {
int x;
int y;
Robot.fromJSON(Map map) : x = map['x'], y = map['y'] {
print('Robot location is $x, $y');
}
}
Causes an error:
Exception: No constructor 'Robot.fromJson' declared in class 'Robot'.
NoSuchMethodError: method not found: 'Robot.fromJson'
Receiver: Type: class 'Robot'
Arguments: [Instance of '_LinkedHashMap']

Dart is case-sensitive
fromJSON vs fromJson

Related

Dart can't access property on a generic type function parameter despite providing the type

I'm trying to specify a function parameter as a generic type T:
enum MyEnum {
Foo,
Bar
}
class DbColumn {
final Function<T>(T value) serializer;
const DbColumn({this.serializer});
}
class MyClass {
static final DbColumn rating = DbColumn(
serializer: <MyEnum>(v) {
var i = v.index;
}
);
}
However when trying to access index on v I get this type error message:
The getter 'index' isn't defined for the type 'Object'.
Try importing the library that defines 'index', correcting the name to the name of an existing getter, or defining a getter or field named 'index'.
When I hover over v in VSC it says that it's of type MyEnum.
If I instead remove the generic type and do a cast like this it works as expected:
class DbColumn {
final Function(dynamic value) serializer;
const DbColumn({this.serializer});
}
class MyClass {
static final DbColumn rating = DbColumn(
serializer: (v) {
var casted = v as MyEnum;
var i = casted.index;
}
);
}
Why is the generic type not working as expected?
EDIT:
What is even weirder is that this example works too if I put it inside MyClass:
x<T>(Function(T) c) {}
y() {
x<MyEnum>((v) {
print(v.index); // No error given and type of v is MyEnum
});
}
EDIT 2: The same problem happens when overriding methods:
abstract class MyInterface {
int someFunction<T>(T value);
}
class MyClass implements MyInterface {
#override
someFunction<MyEnum>(v) {
return v.index; // Gives same error and no intellisense happens in VSC
}
}
Instead of making the function generic, declare the class as generic and it will work as expected. Like this :
enum MyEnum {
Foo,
Bar
}
class DbColumn<T> {
final Function(T value) serializer;
const DbColumn({this.serializer});
}
class MyClass {
static final DbColumn<MyEnum> rating = DbColumn(
serializer: (v) {
var i = v.index;
print('Index : $i');
}
);
}
void main() {
MyClass.rating.serializer(MyEnum.Bar);
}
OUTPUT :
Index : 1

Dart passing generic Function<T>(T t) seems to require cast, all other ways signatures don't match

With the below code as an example I can not figure out how to make the generic typed Function work with out casting as shown. Every other way I try I get some variation of
The argument type 'Null Function(Gift)' can't be assigned to the
parameter type 'dynamic Function(T)'
var present = Present<Gift>(Gift('Fancy Gift'), <T>(Gift t) {
print('${(t as Gift).name} was opened.');
});
or
The getter 'name' isn't defined for the type 'Object'
var present = Present<Gift>(Gift('Fancy Gift'), <Gift>(t) {
print('${t.name} was opened.');
});
Here is the working example with a cast.
void main() {
var present = Present<Gift>(Gift('Fancy Gift'), <T>(t) {
print('${(t as Gift).name} was opened.');
});
present.open();
}
class Present<T> {
final T _item;
final Function<T>(T t) openedCallback;
T open() {
openedCallback.call(_item);
return _item;
}
Present(this._item, this.openedCallback);
}
class Gift {
final String name;
Gift(this.name);
}
There should be a way to do this without a cast right?
Your class definition does not do what you intend:
class Present<T> {
final T _item;
final Function<T>(T t) openedCallback;
...
openedCallback is separately parameterized; its T type parameter is separate and independent from that of Present<T>. There is no need to parameterize openedCallback since you presumably want:
class Present<T> {
final T _item;
final Function(T t) openedCallback;
...
After that, you can do:
var present = Present<Gift>(Gift('Fancy Gift'), (t) {
print('${t.name} was opened.');
});
Note that doing <T>(t) { ... } or <Gift>(t) { ... } is counterproductive. That declares an anonymous function that itself is generic and is has a type parameter named T or Gift respectively.

why do we need Callable classes in dart

What is the use of callable classes in dart lang? Following is the example code available on official dart site.
class WannabeFunction {
call(String a, String b, String c) => '$a $b $c!';
}
main() {
var wf = new WannabeFunction();
var out = wf("Hi","there,","gang");
print('$out');
}
How useful is it add a call function and call it using a class instead of creating a function itself in class
This can be useful to make "named functions":
class _Foo {
const _Foo();
void call(int bar) {}
void named() {}
}
const foo = _Foo();
Which allows both:
foo(42);
and
foo.named();

Dart any differences between with or without abstract keyword?

Hi I just would like to know if there is any difference between giving abstract keyword or not like so.
// with
abstract class A {}
class B extends A {}
// without
class A {}
class B extends A {}
Should I give it?
With abstract you can omit implementations of methods and getters/setters
// with
abstract class A {
int foo();
String get bar;
set baz(String value);
}
var a = A(); // error about instantiating abstract class
class B extends A {
// error about missing implementations
}
var b = B(); // ok
// without
class A {
int foo(); // error about missing implementation
String get bar; // error about missing implementation
set baz(String value); // error about missing implementation
}
class B extends A {}

Why cannot I declare class outside of class in Vala (error: redefinition of struct)?

The example below, test4.vala, compiles and runs:
//// compile with: valac test4.vala
//~ public class TestClass : GLib.Object { // error: redefinition of ‘struct _TestClass’
//~ public int x = 0;
//~ public int y = 0;
//~ public int z = 0;
//~ }
public Test App;
public class Test : GLib.Object {
public class TestClass : GLib.Object { //current
public int x = 0; //current
public int y = 0; //current
public int z = 0; //current
} //current
public TestClass mytc;
public void SetVars() {
mytc = new TestClass();
stdout.printf("SetVars called, %p\n", mytc);
}
public Test(string[] args){
stdout.printf("Test() ctor: ok\n");
stdout.flush();
}
public static int main (string[] args) {
App = new Test(args);
App.SetVars();
stdout.printf("main called\n");
return 0;
}
}
However, if I comment the lines marked "current", and uncomment the commented code, I get this error:
$ valac test4.vala && ./test4
/tmp/test4.vala.c:64:8: error: redefinition of ‘struct _TestClass’
struct _TestClass {
^~~~~~~~~~
/tmp/test4.vala.c:20:16: note: originally defined here
typedef struct _TestClass TestClass;
^~~~~~~~~~
error: cc exited with status 256
Compilation failed: 1 error(s), 0 warning(s)
I still trying to grok Vala, but this kinda leaves me puzzled - why cannot I compile an additional class outside the one carrying main on a same level with it - but I have to instead "include" this other class in the main app class?
It has to do with how GObject works and its naming conventions. The GObject manual has more details, so I'm not going to go into much depth here…
When you create an object, let's call it Foo, in Vala, in the generated C two structs will be created: Foo and FooClass. The former is what people will mostly use in the API and represents an instance of Foo, whereas the latter is used to hold information about the Foo class itself; virtual function pointers are the big thing.
So, with your above code, the generated code will contain Test and TestClass for the outer class, and TestTestClass and TestTestClassClass for the inner class. Once you uncomment the rest of the code, it will try to generate TestClass and TestClassClass, the former of which will conflict with the *Class struct for the outer class that already existed.
You could reproduce the issue a bit more easily with just:
public class Test : GLib.Object { }
public class TestClass : GLib.Object { }
Basically, don't call a class *Class.

Resources