I don't understand why the following example doesn't work:
void main() {
final BaseClass something = ConcreteClass('test');
if (something is I) {
print(something.exists); // The getter 'exists' isn't defined for the type 'BaseClass'.
}
}
abstract interface class I {
String get exists;
}
abstract class BaseClass {}
class ConcreteClass extends BaseClass implements I {
ConcreteClass(this.exists);
@override
final String exists;
}
Am I hitting the "getter" limitation in type promotion mentioned here: https://dart.dev/tools/non-promotion-reasons#not-field ?
If so, how can I solve this without resorting to casting (which I try to avoid)?
Adding exists
to BaseClass
is not an option in my real code.
Also, the release notes for Dart 3.3 says:
Abstract getters are now promotable under the rules of private final field promotion, if there are no conflicting declarations.
... which sounds like what I want?
The problem you are hitting are described here:
https://dart.dev/tools/non-promotion-reasons#subtype-mismatch
In short, the problem is that you are trying to do type promotion which would remove functionality from the something
variable. In this case, if you promote the type to I
, the type of the something
variable would become I
but then, it is no longer a BaseClass
. So since Dart does not have the concept of multiple types on the same variable, it can't say something
are both a BaseClass
and an I
.
A solution would be to do a typecast:
void main() {
final BaseClass something = ConcreteClass('test');
if (something is I) {
print((something as I).exists);
}
}
But since you want to avoid this, you can also declare a new variable. This is actually rather simple if we make use of a pattern:
void main() {
final BaseClass something = ConcreteClass('test');
if (something case I something) {
print(something.exists);
}
}
Here, we declare a new local variable for the if-block called something
if the method variable something
are I
. Since this local something
would be of the type I
, it would not allow calling any method from the BaseClass
class.
If you need to be able to make use of functionality of both I
and BaseClass
, I recommend using a different name of the variable in the pattern.
For more detailed information and solutions, read the link I mentioned in the beginning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With