Dart: Inherit method from abstract class

1,337

In dart there's no inheritance of static members. See Language Specification here-

Inheritance of static methods has little utility in Dart. Static methods cannot be overridden. Any required static function can be obtained from its declaring library, and there is no need to bring it into scope via inheritance. Experience shows that developers are confused by the idea of inherited methods that are not instance methods.

Of course, the entire notion of static methods is debatable, but it is retained here because so many programmers are familiar with it. Dart static methods may be seen as functions of the enclosing library.

To tackle this, you can update your solution like this -

Abstract Parent Class -

abstract class ScreenAbstract extends StatefulWidget {
  final String _name;
  String get routeName => '/$_name';
  ScreenAbstract(this._name, {Key key}) : super(key: key);
}

The Screen Widget that extends the Parent class -

class SomeScreen extends ScreenAbstract {  
  static final String name = "url";
  SomeScreen({Key key}) : super(name, key: key);

  @override
  _SomeScreenState createState() => _SomeScreenState();
}

Then you can access it like this -

Navigator.of(context).pushNamed(SomeScreen().routeName);
Share:
1,337
triple7
Author by

triple7

Updated on December 25, 2022

Comments

  • triple7
    triple7 over 1 year

    Trying to make a generic route "base class", where an abstract class defines a getter that returns the route name. Something like this:

    abstract class ScreenAbstract extends StatefulWidget {
      static String name;
    
      static String get routeName => '/$name';
    
      ScreenAbstract({Key key}) : super(key: key);
    }
    

    Then, any "screen" widget can extend this class:

    class SomeScreen extends ScreenAbstract {
      static final name = 'someScreen';
    
      SomeScreen({Key key}) : super(key: key);
    
      @override
      _SomeScreenState createState() => _SomeScreenState();
    }
    

    Which should then be accessible like this:

    Navigator.of(context).pushNamed(SomeScreen.routeName);
    

    Hoever, when trying that, the linter throws an error: The getter 'routeName' isn't defined for the type 'SomeScreen'.

    What am I doing wrong?

    • jamesdlin
      jamesdlin over 3 years
      ScreenAbstract.routeName is static. static members aren't inherited. You will need to explicitly add a SomeScreen.routeName getter, or callers should use ScreenAbstract.routeName directly.
    • triple7
      triple7 over 3 years
      Gotcha. Can you show how to make it possible to call the getter from the extending class? (By making ScreenAbstract.routeName not static...)
    • jamesdlin
      jamesdlin over 3 years
      You could let ScreenAbstract.routeName remain static and add static String get routeName => ScreenAbstract.routeName; to SomeScreen.
    • triple7
      triple7 over 3 years
      But that would mean that all classes that extend it will have the same value for routeName, No? Whereas I am trying to make it so that each "screen" class will have its own static routeName value.
  • triple7
    triple7 over 3 years
    Right, so basically, I cannot access it statically, but must use a class instance for that. Guess I'll just use an interface to enforce the implementation, rather than inherit the parent class. Thanks!
  • Tanuj
    Tanuj over 3 years
    Yep, Interface would be the proper way to go about this.