Kotlin 中密封和内部有什么区别?

Jus*_*pez 3 modifier kotlin

sealedKotlin 中和之间有什么区别internal?我已阅读 Kotlin 关于密封类和可见性修饰符的文档;但是,我仍然不清楚何时使用sealedvs. internal。也许有人可以提供真实世界的代码示例?

密封课程| Kotlin可见性修饰符 | 科特林资源。

Tar*_*rmo 5

sealed类在所有模块中都可见,但只能在同一模块中扩展。这意味着如果你有这个:

sealed class MyClass {}那么你可以在同一个模块中执行此操作:

class MyExtensionClass: MyClass() {}

但你不能在另一个模块中做同样的事情。但您仍然可以在另一个模块中同时使用MyClass和。MyExtensionClass例如,您可以在另一个模块中执行此操作:

val x: MyClass = MyExtensionClass()
Run Code Online (Sandbox Code Playgroud)

您不能sealed在同一模块或另一个模块中直接实例化类。这意味着你无法在任何地方执行此操作:

val x = MyClass()
Run Code Online (Sandbox Code Playgroud)

所以密封类基本上是一个抽象类,只能在同一个模块中实现。

internal类可以像类一样在同一个模块中使用和扩展sealed,但在另一个模块中则不能这样做。所以你甚至不能在另一个模块中使用或实例化它。您也可以直接实例化一个internal类,只要您在同一模块中执行即可。

所以:用于sealed更好地控制扩展某些东西。例如,您创建一个库,并且希望使用该库中的一个类但不扩展它。internal如果您不希望您的类对其他模块不可见(您创建一个库,但该库中的某些类甚至不应该直接编译时可供库用户使用),请使用

密封类的一个很好的用例:

您构建一个库并拥有一些具有多个不同实现的抽象类或接口,但您希望确保库用户不会添加自己的实现(您不想控制实现细节)。

内部类的一个很好的用例:

您有一些接口和一个创建实现的工厂,但您不希望实现类在编译时对库用户可见。他们只是使用工厂,不需要担心实现。他们可能会构建自己的实现,因此不会使用您提供的工厂,这是可以的。


Ten*_*r04 5

这些并不是相互排斥的。internal sealed class你也可以拥有一个。

internal与可见性有关,与sealed继承规则有关。

internal表示类类型仅在模块内可见。在其他模块中,您甚至不能提及类型的名称。

sealed意味着它是open(可以子类化),但子类(或实现,如果它是密封接口)只能在同一模块中定义,并且编译器会跟踪所有子类的详尽列表。另一个规则是你不能创建它的匿名子类 ( object: MySealedClass)。密封类型的优点是,编译器知道您何时彻底检查了语句when、if/else 链等中的类型。它还可以在库中使用,以确保只有类或接口的已知实现才被使用。传递给它(防止用户创建某些东西的子类并将它们传递到库中)。


奖金:

可见性修饰符关键字:public, internal, private,protected

继承修饰符关键字:open, final,sealed

data并且value还会导致类final隐式地成为副作用。