2014-02-04 3 views
3

Есть ли способ избежать наследования в Дарт? Я ищу что-то вродеИзбегайте наследования класса в Dart

final class MyJavaClass { 
    ... 
} 
+0

Чего вы пытаетесь достичь, предотвращая наследование? –

+0

Простой пример ApiCredentials - нет смысла наследовать что-то из этого класса. –

+0

Если это не имеет смысла, то, вероятно, люди этого не сделают. Но прыгать через эти обручи, чтобы насильственно предотвратить это, кажется излишне сложным. –

ответ

4

Не напрямую, нет.

Вы могли бы написать класс с частными застройщиками и доступ к ним через статические методы:

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); 
    } 
} 

Но есть несколько проблем:

  • Классы внутри одной и той же библиотеки все еще подкласс - видимость в Дарте применяется к библиотекам, а не к отдельным классам.
  • Это много кода, масштабируемое с количеством конструкторов.
  • Он вводит множество статических методов, которые все должны быть названы по-разному.
  • И, конечно же, вы не можете создавать экземпляр класса вне его библиотеки с ключевым словом new.
  • Это предотвращает расширение класса. Реализация «окончательного» класса по-прежнему возможна.

В конечном счете, это немало недостатков для этой функции. Вам решать, действительно ли это стоит.

EDIT

Вопреки тому, что я писал ранее, заводские конструкторы также будут работать, устраняя «неспособный экземпляр с new ключевым словом» недостатком.

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

Кроме того, чтобы проиллюстрировать, почему возможность реализовать не столь окончательный класс является большой проблемой:

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 
    } 
} 

Это псевдо-подклассы будут работать со статическим вариантом выполнения способа, а также.

1

Вы можете добавить частный конструктор.

class MyJavaClass { 
    MyJavaClass._private(); 
} 
0
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 
} 

Если что-то реализует свой окончательный класс, это не проблема, потому что она не будет наследовать логику + это действительно полезно для тестирования и внедрения зависимостей.

+0

Не рекомендуется использовать 'runtimeType'. RuntimeType может быть переопределен подклассами и не надежно возвращает точную информацию. Посмотрите, например, на то, что List возвращает как runtimeType. RuntimeType в основном предназначен для целей отладки. –

+0

@ GünterZöchbauer обновлен. Является ли эта версия достаточно надежной для предотвращения непреднамеренного нарушения? По крайней мере, это нельзя переопределить. – JAre

+0

Я так думаю, если вы хотите использовать отражение, чего следует избегать, особенно если код работает на клиенте. Большая проблема заключается в том, что она ловит ошибку только во время выполнения. Есть ли что-то, что вам не нравится в других решениях или это просто для образовательных упражнений? ;-) –

Смежные вопросы