concrete class method not overrides abstract class - flutter

Having abstract class with methods that should be defined in multiple concrete class. For simplicity sake, here is an example:
abstract class MyAbstractClass extends StatelessWidget{
const MyAbstractClass ({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Text(abstractMethod().toString());
}
int _abstractMethod();
}
class MyConcreteClass1 extends MyAbstractClass {
#override
int _abstractMethod() {
return 42;
}
}
class MyConcreteClass2 extends MyAbstractClass {
#override
int _abstractMethod() {
return 66;
}
}
now when I try to call MyConcreteClass1 or MyConcreteClass2 it gives me the error below:
'MyConcreteClass1' has no instance method '_abstractMethod'
How to call MyConcreteClass1 or MyConcreteClass2 within my screen?
Note that it will work if I called and instance of it like below:
MyConcreteClass1 c = MyConcreteClass1();
int value = c._abstractMethod();
but it should have been called by build method in abstract class, right?

Well, here is an advice for whoever faces this issue:
DON'T use a leading underscore for identifiers that aren’t private.
as this link explains in dart leading underscore in an identifier to mark members and top-level declarations as private. for that it cannot be overridden within inherited classes.

Related

How to create a local Object instance from the generic type

I wanna know how can I create an instance of an Object from the passed generic Type T passed from the super class constructor
this example of what I want to achieve but it's wrong :
class Widget<T> extends StatelessWidget {
Widget({super.key});
final T instanceOfT = T(); // throws 'T' isn't a function.
#override
Widget build(BuildContext context) {
return Text(instanceOfT.exampleStringProperty);
}
}
class ExampleClass {
final String exampleStringProperty;
const ExampleClass({this.exampleStringProperty = "exampleValue"});
}
I'm expecting that I should pass the Type from the generic call when calling the Widget constructor like this:
Widget<ExampleClass>(),
Then an instance of the ExampleClass should be created and works fine.
Any ideas on this ?

Generic Class Return by a provider?

I am sure there is a way to return a dynamic or generic instance of a class from a riverpod FutureProvider?
I can fetch different tracker data from an API. It can be for Physical Activity or Weight data for instance. So far, I tried this but does not work, not even compile:
final trackerDataProvider = FutureProvider.family<AbstractTrackerData, TrackerType>((ref, trackerType) async {
final repository = ref.read(trackerRepositoryProvider);
AbstractTrackerData trackerData =
await repository.getTrackerData(trackerType);
return trackerData;
});
and in my Widget
class PhysicalActivityLandingTrackerScreen extends HookWidget {
#override
Widget build(BuildContext context) {
final trackerData = useProvider(trackerDataProvider(TrackerType.physicalactivity));
...
}
}
and my tracker data classes
class SmokeFree extends AbstractTrackerData {
...
}
class PhysicalActivity extends AbstractTrackerData {
...
}
class Weight extends AbstractTrackerData {
...
}
and the enum
enum TrackerType {
physicalactivity,
exercise,
weeklyweight,
bloodpressure,
saltyfoodsubstitution,
goodfatsubstitution,
medicationuse,
smokefree
}
Yes, because Generic methods have a type parameter (the diamond operator enclosing the type) before the return type of the method declaration. ... Generic methods can have different type parameters separated by commas in the method signature. Method body for a generic method is just like a normal method.
Hence we can say that it is returned by provider.

Dart / Flutter - class doesn't have to implement abstract class's abstract methods?

in Flutter we have class
abstract class PreferredSizeWidget implements Widget {
Size get preferredSize;
}
and
#immutable
abstract class Widget extends DiagnosticableTree {
const Widget({ this.key });
final Key? key;
#protected
#factory
Element createElement();
#override
String toStringShort() {
final String type = objectRuntimeType(this, 'Widget');
return key == null ? type : '$type-$key';
}
#override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense;
}
#override
#nonVirtual
bool operator ==(Object other) => super == other;
#override
#nonVirtual
int get hashCode => super.hashCode;
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
static int _debugConcreteSubtype(Widget widget) {
return widget is StatefulWidget ? 1 :
widget is StatelessWidget ? 2 :
0;
}
}
My question is: Why if we mix in PreferredSizeWidget class we don't have to have implementation for all of the abstract class Widget methods and abstract methods?
I tried to mock up some code
class A implements B {}
abstract class B extends C {}
abstract class C {
void test() {
print("test");
}
}
and got error
Error: The non-abstract class 'A' is missing implementations for these members:
- C.test
class A implements B {
^
lib/main.dart:16:8:
Haven’t run it myself, but in your case A isn’t abstract anymore so it
has to implement everything, in the case of PreferredSizeWidget - you
usually extend/implement/ mixin it on a widget (which already
implements everything from widget) thus leaving you with only
preferredSize
#Norbert515's answer.
The main point is that even though if we mixin/extend PreferredSizeWidget we actually implement all of the Widget methods but as we usually mixin it on a Widget we don't have to make an implicit override of the methods.

Flutter Instance member ‘{0}’ can’t be accessed using static access

I am passing variables from one activity to another in flutter but getting the error "Instance member ‘latitude’ can’t be accessed using static access" I need it converted in that block so I can assign it to a static URL.
class Xsecond extends StatefulWidget {
final double latitude;
final double longitude;
Xsecond(this.latitude, this.longitude, {Key key}): super(key: key);
#override
_Xsecond createState() => _Xsecond();
}
class _Xsecond extends State<Xsecond> {
static String lat = Xsecond.latitude.toString(); // Error: Instance member ‘latitude’ can’t be accessed using static access
...
followed by
...
String url = 'https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${lat},$lng&radius=$radius&type=restaurant&key=$api';
...
In your code both latitude and longitude are defined as non-static i.e. are instance variables. Which means they can only be called using a class instance.
class _Xsecond extends State<Xsecond> {
final xsecond = Xsecond();
static String lat = xsecond.latitude.toString();
...
Please read the basics of any Object Oriented Programming language e.g. Dart, java, C++
However, in your context the first class is your StatefullWidget. So you can access that by the widget field of your state class.
FIX:
class _Xsecond extends State<Xsecond> {
static String lat = widget.latitude.toString();
...
This error occurs if you use non-static variable like static. Let's take a look at this example:
class MyPage extends StatefulWidget {
final foo = Foo();
// ...
}
class _MyPageState extends State<MyPage> {
final newFoo = MyPage.foo; // Error
// ...
}
MyPage.foo isn't a static member but you are using if it was.
To solve this issue, you can either make the variable static
static final foo = Foo();
or
Use widget variable to get hold of the underlying variable.
class _MyPageState extends State<MyPage> {
#override
void initState() {
super.initState();
final newFoo = widget.foo; // No Error
}
// ...
}

How to access it's static constant from instance of an object?

I have an object that has static constant which I need to reach from its instance.
class ChatsScreen extends StatefulWidget {
var arguments;
static const name = ADatas.chatRoute;
ChatsScreen(this.arguments);
createState() => ChatsScreenState();
}
In above class' State object, I want to call static const name. Above class' State object's code:
class ChatsScreenState extends State<ChatsScreen> with RouteHelper{
String userName = "";
var textEditingController = TextEditingController();
#override
void initState() {
getRouteName(widget); //=> as I understand and see on the VSCode, its the ChatsScreen object.
super.initState();
}
}
I'm trying to implement an interface so I don't know the actually class name while writing the interface. And I thought that I can reach its static constant if I know its actual class. And I wrote something like this but it seems not to be possible. I guess I have a misunderstanding.
class RouteHelper{
String getRouteName(dynamic instance){
if(instance is StatefulWidget){
return instance.runtimeType.name; // => !!!
}
}
}
Note: I'm not trying to get the route name in actual. It's just a concept that i used in this question, so please don't refer better way to get the route name in flutter.
You can't do it like that, people have talked about this in this issue.
However you can kinda do it using class members and typing system.
abstract class Routed {
String getClassRoute();
}
class ChatsScreen extends StatefulWidget implements Routed {
var arguments;
static const name = "myexampleroutename";
ChatsScreen(this.arguments);
createState() => ChatsScreenState();
#override
String getClassRoute() {
return ChatsScreen.name;
}
}
class RouteHelper {
String getRouteName(Routed instance) {
return instance.getClassRoute();
}
}
I said you can't, but with dart:mirrors it is possible, however it is banned on Flutter packages. There is reflectable package that tries to fix that using code generation, but I am not aware of it's status/reliability.