Search code examples
flutterdartabstractiondart3

How I can declare interface methods in Dart 3?


I have recently migrated from Dart 2 to Dart 3 and have noticed that Class Modifiers have been added, including interface class. They work perfectly fine when setting properties, but when it comes to methods, it throws an error stating that I need to convert the class to abstract. Based on logic, I understand that interfaces should not have method bodies. Here's an example:

Works fine:

interface class Foo {
  late String bar;
}

Throws dartconcrete_class_with_abstract_member:

interface class Foo {
  late String bar;
  
  // 'getFormattedBar' must have a method body because 'Foo' isn't abstract.
  // Try making 'Foo' abstract, or adding a body to 'getFormattedBar'.
  // (dartconcrete_class_with_abstract_member)
  String getFormattedBar(); 
}

How I can declare interface methods in Dart 3?

I was hoping to define methods in the interface (as per the definition of an interface, of course) and then later establish their concrete implementations with their respective bodies in the implementing classes. Instead, I'm being forced to place an empty body in the interface, which doesn't make any sense. It would be ideal to have something like:

interface class Foo {
  late String bar;
  String getFormattedBar(); 
}

Solution

  • The interface keyword makes sure that you can only implement the class, and not mixin nor extend the class. Or in other words, it makes sure that you cannot inherit from the class.

    You can still construct the class if the interface class modifier is the only class modifier you use. This means that the methods need to have a concrete implementation.

    // Can be constructed and implemented, but not extended nor mixed in.
    interface class Foo {
    
      // Implementation needed
      String bar() {
        return 'baz';
      }
    }
    

    If you also add the abstract class modifier then you can not construct the class and the methods does not have to have a concrete implementation.

    // Can not be constructed.
    // Can be implemented, but not extended nor mixed in.
    abstract interface class Foo {
    
      // Implementation should be left out
      String bar();
    }