Mike Mitterer
Mike Mitterer

Reputation: 7180

Avoid inheritance of class in Dart

Is there a way to avoid inheritance in Dart? I'm looking for something like

final class MyJavaClass {
    ...
}

Upvotes: 7

Views: 2865

Answers (3)

JAre
JAre

Reputation: 4756

import 'dart:mirrors';

class Final {
  Final() {
    InstanceMirror im = reflect(this);
    if (im.type.reflectedType != Final) throw "Final can't be inherited";
  }
}

class ExtendsFinal extends Final {}
//class WithFinal extends Object with Final{} //mixin can't declare constructor

void main() {
  new ExtendsFinal(); // ExtendsFinal !=  Final
}

If something implements your final class it's not a problem, because it will not inherit logic + it's really useful for testing and dependency injection.

Upvotes: 0

MarioP
MarioP

Reputation: 3832

Not directly, no.

You could write a class with private constructors and access them via static methods:

class MyFinalClass {
  MyFinalClass._ctor1() {}
  MyFinalClass._ctor2(String param1, String param2) {}
  static MyFinalClass getInstance() {
    return new MyFinalClass._ctor1();
  }
  static MyFinalClass getInstanceWithParams(String param1, String param2) {
    return new MyFinalClass._ctor2(param1, param2);
  }
}

But this has multiple problems:

  • Classes inside the same library can still subclass it - visibility in Dart applies to libraries, not single classes.
  • It's a lot of code, scaling with the amount of constructors.
  • It introduces lots of static methods, which all have to be named differently.
  • And of course, you can't instantiate the class outside its library with the new keyword.
  • This only prevents extension of a class. Implementing the "final" class is still possible.

Ultimately, these are quite a few drawbacks for this feature. It's up to you to decide if it is really worth it.

EDIT

Contrary to what I have written before, factory constructors would also work, eliminating the "unable to instantiate with new keyword" drawback.

class MyFinalClass {
  factory MyFinalClass.ctor1() {}
  factory MyFinalClass.ctor2(String param1, String param2) {}
  void method1() {}
  void method2() {}
}

Also, to illustrate why the ability to implement the not-so-final class is a big problem:

class Sub implements MyFinalClass {
  MyFinalClass _d;
  Sub.ctor1() {
    _d = new MyFinalClass.ctor1();
  }
  Sub.ctor2(String p1, String p2) {
    _d = new MyFinalClass.ctor2(p1,p2);
  }
  void method1() => _d.method1();
  void method2() {
    // do something completely different
  }
}

This pseudo-subclassing would work with the static method variant as well.

Upvotes: 7

Günter Zöchbauer
Günter Zöchbauer

Reputation: 657198

You can add a private constructor.

class MyJavaClass {
  MyJavaClass._private();
}

Upvotes: 4

Related Questions