34

In an abstract class, I wish to define static methods, but I'm having problems.

In this simple example

abstract class Main {
  static String get name;
  bool use( Element el );
}

class Sub extends Main {
  static String get name => 'testme';
  bool use( Element el ) => (el is Element);
}

I receive the error:

function body expected for method 'get:name' static String get name;

Is there a typo in the declaration, or are static methods incompatible with abstract classes?

nbro
  • 15,395
  • 32
  • 113
  • 196
cc young
  • 18,939
  • 31
  • 90
  • 148

2 Answers2

37

Dart doesn't inherit static methods to derived classes. So it makes no sense to create abstract static methods (without implementation).

If you want a static method in class Main you have to fully define it there and always call it like Main.name

== EDIT ==

I'm sure I read or heard some arguments from Gilad Bracha about it but can't find it now.

This behaviour is IMHO common mostly in statically typed languages (I don't know many dynamic languages). A static method is like a top level function where the class name just acts as a namespace. A static method has nothing to do with an instantiated object so inheritance is not applicable. In languages where static methods are 'inherited' this is just syntactic sugar. Dart likes to be more explicit here and to avoid confusion between instance methods and static methods (which actually are not methods but just functions because they don't act on an instance). This is not my primary domain, but hopefully may make some sense anyways ;-)

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    do you know if there a rationale for not to inheriting static methods? – cc young Dec 23 '13 at 10:56
  • Extended the answer because the text size exceeds max comment length. – Günter Zöchbauer Dec 23 '13 at 11:14
  • @ccyoung My guess is that it's more confusing than beneficial. One can emulate static inheritance by using reflection, i.e. by calling a super-type's implementation or calling a static method by name for getting 'overridden' behavior. Would be interesting to know what's the real answer is. – Andrey Chaschev Dec 23 '13 at 11:18
2

Looks like you are trying to 'override' a static method. I'm not sure what you are trying to achieve there. I'm not aware of any OO languages that support that (and not sure how they could).

A similar question in Java might help clarify Polymorphism and Static Methods

Note also that it is considered bad practice to refer to statics from an instance of the class in Java (and other OO languages). Interestingly I noticed Dart does not let you do this so is in effect removing this bad practice entirely.

So you couldn't even fool yourself into thinking it would behave polymorphically in Dart because you can't call the static from the instance.

Community
  • 1
  • 1
Anders
  • 1,337
  • 1
  • 8
  • 17
  • 3
    Swift has Type Methods with the keyword `class`, which is similar to static, but you can override it. – JIE WANG Aug 21 '20 at 08:00
  • Yes, afaik Swift is the only language that supports it (and many other revolutionary things). This request is open to support this in Dart: https://github.com/dart-lang/language/issues/356. – Nader Ghanbari Nov 18 '20 at 22:01
  • Objective-C as well :) – Aleksey Sep 09 '21 at 05:50
  • And Python's `@classmethod`s – Anakhand Dec 22 '22 at 20:49
  • 2
    That feature would be useful for an `ORM` framework. It would allow creating something like `abstract static String tableName`, then a concrete class can `@override static String tableName = 'users'` and do something like `query = 'SELECT * FROM $tableName'`, without having to repeat the `tableName` string or creating a regular final field in memory for each instance just to fulfill this behavior. – caiohamamura Apr 13 '23 at 13:32
  • @caiohamamura totally agree with you. Did you find any way to archieve it? – Àlex Garcia Jul 12 '23 at 05:59