Is it possible to construct an instance of a class with an instance of its super class without calling every field one by one ( in the below code, I call bar.name )?
When I do, Foo foo = bar, I get
Instance of 'Bar': type 'Bar' is not a subtype of type 'Foo'
However, Foo extends bar
void main() {
Bar bar = Bar('bar');
Foo foo2 = Foo(null, bar.name); // Works but need to call every field
print(foo2.name);
Foo foo = bar; // How to make this work ?
}
class Bar{
final String name;
Bar(this.name);
}
class Foo extends Bar{
final int age;
Foo(this.age, String name) :super(name);
}
That is not possible beacause it has no sens. Foo is a Bar (it extends Bar), but a Bar is not a Foo. So you can't assign it to a Foo.
Indeed, as Foo extends Bar, there are things missing in Bar that are present in Foo.
Back to your original question, if you want to create a Foo without age you can do something like that :
class Foo extends Bar{
final int age;
Foo(this.age, String name) :super(name);
factory Foo.withoutAge(String name) => Foo(null, name);
}
void main() {
Foo foo2 = Foo.withoutAge('bar');
print(foo2.name);
}
Related
As a recent convert from the land of duck typing, I'm asking this question because I suspect others may have found themselves in this corner of thought as well. I want baz to be both final and public. Can I do that? If so, how?
class Foo {
final Bar bar;
Baz baz;
Foo({this.bar}) {
baz = _someFunction(bar);
}
Baz _someFunction(Bar bar) {
...
return baz;
}
}
As Christopher Moore noted in the comments, if Dart's null-safety features are enabled, you can use the late keyword to initialize final members:
class Foo {
final Bar bar;
late final Baz baz;
Foo({this.bar}) {
baz = _someFunction(bar);
}
...
}
Alternatively, even without null-safety, if you can make _someFunction not be an instance method on Foo you could use a factory constructor as an intermediary:
class Foo {
final Bar bar;
final Baz baz;
Foo._(this.bar, this.baz);
factory Foo({Bar bar}) {
return Foo._(bar, _someFunction(bar));
}
...
}
Also, be aware that the final keyword prevents the field from referring to a different object, but it does not make that object immutable.
If _someFunction is static, or can be made static, then you can call it in the initializer list:
class Foo {
final Bar bar;
final Baz baz;
Foo(this.bar) : baz = _someFunction(bar);
static Baz _someFunction(Bar bar) { ... }
}
If the computation is more complicated than what a single function can do, perhaps computing multiple values at the same time, then you can use a factory constructor to compute, and a private generative constructor to construct:
class Foo {
final Bar bar;
final Baz baz;
factory Foo(Bar bar) {
// long complex computation.
return Foo._(bar, baz);
}
Foo._(this.bar, this.baz);
}
If you can delay the computation until baz is first read, then you can use a late variable with initializer:
class Foo {
final Bar bar;
late final Baz baz = _someFunction(bar);
Foo(this.bar);
Baz _someFunction(Bar bar) { ... }
}
That still ensures that baz has no setter.
(You can even add a read of baz in the constructor, to ensure that it's computed early. Sligthly confusing to see a constructor body of { baz; }, but it works.
Otherwise, I'd probably make baz a getter backed by a private field, and then do whatever makes most sense with that field:
class Foo {
final Bar bar;
Baz? _baz;
Baz get baz => _baz!;
Foo(this.bar) {
_baz = _someFunction(bar);
}
Baz _someFunction(Bar bar) { ... }
}
or
class Foo {
final Bar bar;
late final Baz? _baz;
Baz get baz => _baz!;
Foo(this.bar) {
_baz = _someFunction(bar);
}
Baz _someFunction(Bar bar) { ... }
}
I would avoid a public late final variable with no initializer.
Such a variable has a public setter. It's visible in the API, and someone might feel inclined to call it (it'll throw because you already initialized it once, but it's still messy).
That only matters if it's a public API. For an internal API, ... do whatever. If anyone disagrees, they can change the code anyway.
I'm working on a library, and I have a implementation pattern users are required to follow:
class MyView extends LibView {
static Foo f = Foo();
#override
void render(){
use(f); // f should be static, otherwise things not work correctly
}
}
I would like to tell the compiler that, if someone ever does this, it's incorrect:
class MyView {
Foo f = Foo(); // Error: Foo can only be used in Static field.
...
}
Anyone know if this is possible? I find it really hard to find good docs on these sorta of language details when it comes to dart.
[EDIT] Since the "why" question always comes up, imagine something like:
class ViewState{
Map<int, Object> props = {};
}
ViewState _state = ViewState();
class View {
View(this.state);
ViewState state;
static int _key1 = getRandomInt();
void render(){
print(state(_key1))
}
}
// These should both print the same value off of state since the 'random' int is cached
View(_state);
View(_state);
If the key's were not static, everything would compile fine, but they would not print the same results.
What you properly need are a singleton which can be created in different ways in Dart. One way is to use a factory constructor like this:
class Foo {
static final Foo _instance = Foo._();
factory Foo() => _instance;
// Private constructor only used internally
Foo._();
}
void main() {
final a = Foo();
final b = Foo();
print(identical(a, b)); // true
}
By doing it like this, there will only be one instance of Foo which are then shared each time an instance are asked for. The instance are also first created the first time it is asked for since static variables in Dart are lazy and only initialized when needed.
I just want to do the functional equivalent of
int someUniqueKey = 0, or MyViewEnums.someUniqueKey but do it with a typed object rather than a int/enym, like: Object<Foo> someUniqueKey = Object<Foo>(). In order for this to work with Objects, it needs to be static. It's similar to how int someUniqueKey = random.nextInt(9999) would have to be static in order to be used as a key that all instances could share. That way keys are auto-managed and unique, and people don't need to assign int's, strings, or whatever. It also has the advantage of letting me use the type later for compile time checks.
bool prop = getPropFromRef(_prop1Ref); //Will throw error prop1Ref is not Ref<bool>
I think I've figured out something that does the trick using darts package-level methods.
class Ref<T> {}
// Re-use existing ref if it already exists
Ref<T> getRef<T>(Ref<T> o) => o ?? Ref<T>();
class RefView {}
// In some other package/file:
class MyView extends RefView {
static Ref<bool> prop1Ref = getRef(prop1Ref);
static Ref<int> prop2Ref = getRef(prop2Ref);
}
This will make sure that prop1 and prop2 have the same values across all instances of MyView and it will throw an error if these are not static (since you can not pass an instance field before Constructor)
This still has the downside of a potential hard to spot error:
class MyView extends RefView {
static Ref<bool> prop1 = getRef(prop1);
static Ref<bool> prop2 = getRef(prop1); // passing prop1 to prop2's getRef, and they have the same<T>, compiler will miss it
}
But I think it might be preferable than having this potential error:
class MyView extends RefView {
//Both of these will fail silently, keys will change for each instance of MyView
Ref<bool> prop1 = getRef(prop1);
Ref<bool> prop2 = getRef(prop2);
}
I'm able to do something like the following in TypeScript
class Foo {
private constructor () {}
}
so this constructor is accessible only from inside the class itself.
How to achieve the same functionality in Dart?
Just create a named constructor that starts with _
class Foo {
Foo._() {}
}
then the constructor Foo._() will be accessible only from its class (and library).
A method without any code must be something like this
class Foo {
Foo._();
}
Yes, It is possible, wanna add more information around it.
A constructor can be made private by using (_) underscore operator which means private in dart.
So a class can be declared as
class Foo {
Foo._() {}
}
so now, The class Foo doesn't have a default constructor
Foo foo = Foo(); // It will give compile time error
The same theory applied while extending class also, It's also impossible to call the private constructor if it declares in a separate file.
class FooBar extends Foo {
FooBar() : super._(); // This will give compile time error.
}
But both above functionality works if we use them in the same class or file respectively.
Foo foo = Foo._(); // It will work as calling from the same class
and
class FooBar extends Foo {
FooBar() : super._(); // This will work as both Foo and FooBar are declared in same file.
}
you can create following class in order to get a singleton instance
class Sample{
factory Sample() => _this ??= Sample._();
Sample._(); // you can add your custom code here
static Sample _this;
}
Now in the main function you can call the sample constructor
void main(){
/// this will return the _this instace from sample class
Sample sample = Sample();
}
just use abstract class.
Because you can't instantiate abstract class
Simply i have to classes child and parent class i am new in dart language all i need to assign super class properties from child class
this is super class structure
class Trip{
final int id;
final String title;
final double price;
Trip({this.id,this.title,this.price});
}
and this is child class
class FullTrip extends Trip{
final String data;
FullTrip({this.data}) : super(id:id,title:title,price:price);
}
sure this not working at all
the question is : how can i initialize instance from FullTrip and pass variable for FullTrip and Trip(super class)
thanks in advance
You need to repeat the parameters in the subclass.
class FullTrip extends Trip{
final String data;
FullTrip({this.data, int id, String title, double price}) : super(id:id,title:title,price:price);
}
There are discussions about reducing such boilerplate for constructors, but nothing is decided yet as far as I know.
User super-parameters, which were added in Dart 2.17. For example, say this is your class:
class Parent {
Parent({
int? i,
bool b = false,
required String s,
});
}
Old way (boilerplate code)
Earlier you had to do something like this:
class Child extends Parent {
Child({
int? i,
bool b = false,
required String s,
}) : super(
i: i,
b: b,
s: s,
);
}
New way (neat and clean)
But now you can get rid of those boilerplate code.
class Child extends Parent {
Child({
super.i,
super.b = false,
required super.s,
});
}
If you want to re-initialize in a subclass the not private variables of an extended or implemented upper class before compiling, simply use #override. Look at this example
(if you want to try the code, have in mind it supports null safety. If your test doesn't, simply delete the ? signs.)
class Go {
String? name = "No name";
}
class Foo implements Go { //use either implements or extends
#override
String? name = "Foo";
}
class Doo extends Go { //use either implements or extends
#override
String? name = "Doo";
}
Use case example: In the code above, you can see that in our upper class we have this String name variable. Then in the subclasses we can simply override that variable. After that, in main we can now for example do something like iterating through a List<Go>, access what we wanted to and then trigger something, like printing the name:
void main() {
List<Go> foos = [
Go(),
Foo(),
Doo(),
];
for(Go x in foos){
print(x.name);
}
}
Output:
No name
Foo
Doo
This works if you use either the extends or implements keywords.
Suppose I have this situation:
class Foo {
final _bar;
Foo([bar = 'hello']);
}
In Dart, how do I initialize _bar, given that it's private?
You can use the initializer list.
class Foo {
final _bar;
Foo([bar = 'hello']) : _bar = bar;
}
The initializer list is run before the constructor body.