ByteCode, dedicated to share the latest technology original articles, involving Kotlin, Jetpack, translation, system source code, LeetCode/point Offer/multithreading/domestic and foreign large factory algorithm problems and so on a series of articles.

This is the third article in the Sealed Classes series. The previous articles covered the power of Sealed Classes from a variety of perspectives, including principles, optimization, and practice.

What is Kotlin Sealed? The article contains the following contents:

  • Sealed Classes
  • What are the pros and cons of enums, abstract Classes, and Sealed Classes?
  • When are enumerations and Sealed Classes used?
  • Why Sealed Classes are used to represent a restricted class hierarchy?
  • How do I use Sealed Classes in my project?
  • How did Kotlin do this?
  • .

Sealed classes are better than tagged classes in Kotlin.

  • What is Tagged Classes?
  • What are the advantages and disadvantages of Tagged Classes, as well as their impact on the project?
  • How can I optimize existing code using Sealed Classes, and what are the benefits?

In this article, I will introduce Sealed Classes’ new features and principles for Kotlin 1.5.0. Before I start, I will briefly review the previous article.

Sealed Classes

What are Sealed Classes?

Sealed Classes is used to describe a class hierarchy that is restricted.

  • Sealed Classes are used to represent hierarchies: subclasses can be any class, data class, Kotlin object, generic class, or even another Sealed class
  • Sealed Classes are restricted: they must be used within the same file or within Sealed Classes. Prior to Kotlin 1.1, the rules were much stricter and subclasses could only be used within Sealed Classes

Sealed Classes advantages:

  • Sealed Classes make responsibility between Classes clear and improve code readability
  • Extensible, you can add new parameters or subclasses without modifying the original code structure
  • Each class does not contain extraneous fields, reducing the memory footprint of objects to some extent
  • Sealed Classes can be used in conjunction with the WHEN expression to make sure that all branches under the WHEN statement can be accessed by shortcut keysMac/Win/Linux: Alt + EnterAutomatically generated, the effect is as follows:

Let’s take a look at some of the optimizations made by Sealed Classes in the new version of Kotlin 1.5.0.

Sealed Classes have evolved

In May 2021, Kotlin officially released 1.5.0, which brings several useful features. In this article, we will cover Sealed Classes, check out What’s New in Kotlin 1.5.0 for more information.

In Kotlin 1.0, subclasses could only be used inside Sealed Classes because Sealed Classes were compiled to an abstract class and the default constructor was privatized. So subclasses must be nested within the Sealed Classes class.

In Kotlin 1.1, top-level Sealed Classes were allowed to be in the same file as their top subclasses, because the compiler automatically generated a public constructor that called the parent class’s public constructor. The Kotlin compiler did this for us.

In Kotlin 1.5.0, Sealed Classes have been relaxed to ensure that they and their subclasses are under the same package name and module. The Kotlin compiler does this for us.

Why did Kotlin upgrade Sealed Classes? In the previous article in Kotlin, Sealed Classes have many advantages over tagged Classes, but they also have many disadvantages, which is why you need to upgrade Sealed Classes:

  • A subclass of Sealed Classes, restricted to a single parent class
  • Putting all the code in one file can result in a bloated and unreadable file, as shown below
sealed class Color { class Red : Color() class Blue : Color() // ...... Sealed class Figure {abstract fun draw()} class Rectangle(val color: color) : Figure() { override fun draw() { } } class Round(val color: Color) : Figure() { override fun draw() { } } class Triangle(val color: Color) : Figure() { override fun draw() { } } ...... // Use Mac/Win/Linux: Alt + Enter to generate fun drawFigure(figure: Figure) { when (figure) { is Rectangle -> TODO() is Round -> TODO() is Triangle -> when (figure.color) { is Color.Blue -> TODO() is Color.Red -> TODO() } } }Copy the code

In Kotlin 1.1, we were limited to a single file, which only grew larger as the demand increased. Now that we have relaxed the restriction, we can split the subclasses into separate files, further improving the readability of the code.

  • Only top-level Sealed Classes and their top-level subclasses are allowed in the same file. For non-top-level Sealed Classes, all subclasses should be declared internally. The following code will fail to compile

As you can see, Sealed Classes are still not flexible enough. Yellow is not a top-level subclass of Color and will not compile properly. Koltin 1.5.0 has made this code more readable and more flexible.

It is also possible to declare protected constructors in Sealed Classes. The default constructor for all Sealed Classes before 1.5.0 was private, but after 1.5.0 the default constructor is protected.

Sealed class Figure {constructor() // default protected private constructor(area: Double) : this()}Copy the code

It is not allowed to declare it public, because the compiler will generate it automatically, and if it is declared public it will generate an error:

Let’s take a look at what the decompiled Java code does with the protected constructor. Tools → Kotlin → Show Kotlin Bytecode.

public abstract class Figure { private Figure() { } private Figure(double area) { this(); } // $FF: synthetic method public Figure(DefaultConstructorMarker $constructor_marker) { this(); } // $FF: synthetic method public Figure(double area, DefaultConstructorMarker $constructor_marker) { this(area); }} public Rectangle extends Figure {public Rectangle() {super(1.0d, (Rectangle constructorMarker)null); }}Copy the code

As you can see, the generated constructor is still private, except that the compiler automatically generates the public constructor and calls the parent class’s public constructor in the subclass constructor. In addition to these changes, another important feature is the addition of a Sealed Interface.

Note:

If you have upgraded to Kotlin 1.5.0 and the compiler still prompts you with an error, add the following code to build.gradle.

CompileKotlin {kotlinOptions {languageVersion = "1.5"}}Copy the code

Sealed Interface

Sealed Interface, like Sealed Classes, is used to represent a restricted class hierarchy, so it has all the benefits of Sealed Classes. Sealed Classes has all the same features Sealed Interface has.

The difference, however, is that Sealed Classes are restricted to a single parent class, whereas Sealed Interfaces support a more flexible restricted class hierarchy because subclasses can implement multiple Sealed Interfaces, as shown below.

// IColor.kt
sealed interface IColor
class Red : IColor
class Blue : IColor

// IArea.kt
sealed interface IArea {
    fun area(): Double
}

// IFigure.kt
sealed interface IFigure

class Round() : IFigure, IColor

class Rectangle(val length: Double, val width: Double) : IFigure, IArea, IColor {
    override fun area(): Double = length * width
}
Copy the code

Sealed Interface allows multiple implementations of its subclasses, which makes the code more flexible, but it is restricted to the same package name and module as Sealed Classes. Breaking this restriction can cause compilation errors.

In this article, we will discuss the advantages and disadvantages of Sealed Classes and Sealed Interface. Kotlin 1.5.0 has also added some additional features. This will be covered in a future article.


This is the end of the article, if it is helpful to give me a thumbs up is the biggest encouragement

More code, more articles

Welcome to the public account: ByteCode, continue to share the latest technology



Finally, I recommend the projects and websites I have been updating and maintaining:

  • Androidx-jetpack-practice androidX-Jetpack-practice androidX-Jetpack-Practice androidX-Jetpack-Practice AndroidX-Jetpack-Practice

  • LeetCode/multiple thread solution, language Java and Kotlin, including a variety of solutions, problem solving ideas, time complexity, spatial complexity analysis

    • Job interview with major companies at home and abroad
    • LeetCode: Read online
  • Android10 Source code Analysis series of articles, understand the system Source code, not only help to analyze the problem, in the interview process, is also very helpful to us, the warehouse continues to update, welcome to check android10-source-Analysis

  • Collate and translate a series of selected foreign Technical articles, each Article will have a translator’s thinking part, a more in-depth interpretation of the original text, the warehouse continues to update, welcome to visit the Technical-Article-Translation

  • “Designed for Internet people, navigation of domestic and foreign famous stations” includes news, sports, life, entertainment, design, product, operation, front-end development, Android development and so on. Welcome to check the navigation website designed for Internet people

Article history

  • The sealed class in Kotlin is superior to the tagged class
  • What did LeetCode learn from going from 0 to 200
  • What is Kotlin Sealed? Why does Google use it all
  • Android 12 behavior changes that affect applications
  • AndroidStudio
  • Kotlin’s Technique and Principle Analysis that few people know (1)
  • Kotlin’s Technique and Principle Analysis that few people know (II)
  • All aspects of Hilt and Koin performance were analyzed
  • PokemonGo Jetpack + MVVM minimalism
  • Kotlin StateFlow search features practice DB + NetWork
  • The end of the Kotlin plugin and the rise of ViewBinding
  • Surprisingly simple, DataBinding and ViewBinding