简体   繁体   中英

What is the difference between sealed and internal in Kotlin?

What is the difference between sealed and internal in Kotlin? I have read Kotlin's documentation on sealed classes and visibility modifiers; however, it is still not clear to me when to use sealed vs. internal . Maybe someone could provide real-world code samples?

Sealed classes | Kotlin & Visibility modifiers | Kotlin resources.

sealed class will be visible in all modules, but extendable only in the same module. This means if you have this:

sealed class MyClass {} then you can do this in the same module:

class MyExtensionClass: MyClass() {}

But you can't do the same thing in another module. But you can still use both MyClass and MyExtensionClass in another module. For example you can do this in another module:

val x: MyClass = MyExtensionClass()

You can't instantiate a sealed class directly neither in the same or another module. This means you can't do this nowhere:

val x = MyClass()

So sealed class is basically an abstract class which can only be implemented in the same module.

internal class can be used and extended in the same module just like a sealed class, but you can do neither in another module. So you can't even use or instantiate it in another module. Also you can directly instantiate an internal class as long as you are doing it in the same module.

So: Use sealed to better control extending something. For example you create a library and you want a class from this library to be used but not extended. Use internal if you wan't your class to be invisible to other modules (you create a library, but certain class in this library shouldn't even be directly compile time usable by libraries users)

A good use case for sealed class:

You build a library and have some abstract class or interface which has multiple different implementations, but you want to make sure the libraries user doesn't add its own implementations (you wan't to be in control of implementation details).

A good use case for internal class:

You have some interface and a factory that creates implementations, but you don't want the implementing class to be compile-time visible to libraries users. They just use the factory and don't need to worry about the implementation. They might build their own implementation though and therefor not use the factory you provided and this is OK.

These are not mutually exclusive. You can have an internal sealed class as well.

internal is about visibility, and sealed is about inheritance rules.

internal means the class type is only visible within the module. In other modules, you can't even mention the name of the type.

sealed means it is open (can be subclassed), but subclasses (or implementations if it's a sealed interface) can only be defined in the same module, and the compiler keeps track of an exhaustive list of all subclasses. Another rule is that you can't create anonymous subclasses of it ( object: MySealedClass ). The advantage of a sealed type is that the compiler knows when you've exhaustively checked a type in when statements, if/else chains, etc. It can also be used in a library to ensure that only known implementations of a class or interface are ever passed to it (prevent users from creating subclasses of something and passing them into the library).


Bonus:

Visibility modifier keywords: public , internal , private , protected

Inheritance modifier keywords: open , final , sealed

data and value also cause a class to be final implicitly as a side effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM