在Java\Kotlin中,我们有一个String
类,它是最终的且不可变的。
我试图用final
关键字标记类,但看起来这是不允许的。
所以,我有点困惑,如何在Dart中声明最终类?
注意:情况是-我想在外部实例化这个类,但禁止扩展它。所以使用私有构造函数-这不是我的情况
您可以通过为类提供私有构造函数来从java实现这种final
效果,这将防止类被扩展,但也会防止类被实例化(仅在同一文件中两者都有可能(:
class MyString {
MyString._(); // use _ for private constructor.
static void print(String s) {
print(s);
}
}
使用呼叫
String message = "Hello World";
MyString.print(message);
Dart认为我们都是成年人,因此防止类扩展是设计的一部分,开发者有责任拥有清晰的类名,而不是语言的一部分:
避免扩展一个不打算被子类化的类
如果构造函数从生成构造函数更改为工厂构造函数,则调用该构造函数的任何子类构造函数都将中断。此外,如果一个类更改了它在此调用的自己的方法中的哪一个,这可能会破坏覆盖这些方法的子类,并期望它们在某些点被调用。
final与Java的含义差异
Dart对什么是final
有一个非常简单的定义:Dart中的变量只能设置一次,id est:是不可变的。
词尾和常量如果您从未打算更改变量,请使用final或const来代替var或添加到类型中
最终变量只能设置一次;const变量是一个编译时常量。(Const变量是隐式的final。(final顶级或类变量在第一次使用时初始化。
除了使构造函数私有化并通过静态工厂实例化对象的方法外,您还可以使用包meta和将最终类注释为密封:
@sealed
class Z{}
这将向包的用户发出信号,表示此类不应被扩展或实现。例如,在vscode中,尝试扩展类Z
:
class Z1 extends Z{}
导致以下警告:
The class 'Z' shouldn't be extended, mixed in,
or implemented because it is sealed.
Try composing instead of inheriting, or refer
to its documentation for more information.dart(subtype_of_sealed_class)
飞镖分析仪也会发现这个问题:
$ dart analyze
Analyzing test... 0.8s
info • lib/src/test_base.dart:3:1 •
The class 'Z' shouldn't be extended, mixed in, or implemented because it
is sealed. Try composing instead of inheriting, or refer to its
documentation for more information. • subtype_of_sealed_class
您可以使用工厂命名构造函数和私有命名构造函数,如下所示:
class NonExtendable {
NonExtendable._singleGenerativeConstructor();
// NonExtendable();
factory NonExtendable() {
return NonExtendable._singleGenerativeConstructor();
}
@override
String toString(){
return '$runtimeType is like final';
}
}
在客户端代码中,在同一个库或另一个库中,可以创建一个实例,例如:
// Create an instance of NonExtendable
print ('${NonExtendable()}');
尝试扩展它,类似
class ExtendsNonExtendableInSameLibrary extends NonExtendable {
ExtendsNonExtendableInSameLibrary._singleGenerativeConstructor() : super._singleGenerativeConstructor();
factory ExtendsNonExtendableInSameLibrary() {
return ExtendsNonExtendableInSameLibrary._singleGenerativeConstructor();
}
}
将在同一个库(相同的"源文件"(中工作,但不能在另一个库中工作,从任何客户端代码的角度来看,使类NonExtendable
与Java中的"final"相同。