Neste tutorial, estaremos explorando a Classe Selada do Kotlin. O que são? Qual é o seu uso? Abordaremos todas essas questões abaixo.
Classe Selada do Kotlin
Em termos simples, como o nome sugere, as classes seladas são fechadas, tornando-as restritas. As classes seladas são usadas para representar hierarquias de classes restritas, onde o objeto ou o valor pode ter valor apenas entre um dos tipos, fixando assim suas hierarquias de tipo. As classes seladas são comumente usadas em casos em que você sabe que um determinado valor deve estar entre um conjunto dado de opções.
Implementando Classes Seladas no Kotlin
As classes seladas no Kotlin são implementadas da seguinte maneira.
sealed class A{
class B : A()
class C : A()
}
Para especificar uma classe selada, você precisa adicionar o modificador sealed
. Uma classe selada não pode ser instanciada. Portanto, são implicitamente abstratas. O seguinte NÃO funcionará.
fun main(args: Array<String>)
{
var a = A() //compiler error. Class A cannot be instantiated.
}
Os construtores de uma classe selada são privados por padrão. Todas as subclasses de uma classe selada devem ser declaradas no mesmo arquivo. As classes seladas são importantes para garantir a segurança de tipos restringindo o conjunto de tipos apenas durante o tempo de compilação.
sealed class A{
class B : A()
{
class E : A() //this works.
}
class C : A()
init {
println("sealed class A")
}
}
class D : A() //this works
{
class F: A() //This won't work. Since sealed class is defined in another scope.
}
Criando uma classe selada com construtores.
sealed class A(var name: String){
class B : A("B")
class C : A("C")
}
class D : A("D")
fun main(args: Array<String>) {
var b = A.B()
var d = D()
}
Adicionando a Classe de Dados e o Objeto em uma classe selada.
fun main(args: Array<String>) {
val e = A.E("Anupam")
println(e) //prints E(name=Anupam)
var d = A.D
d.name() //prints Object D
}
sealed class A{
class B : A()
class C : A()
object D : A()
{
fun name()
{
println("Object D")
}
}
data class E(var name: String) : A()
}
Diferença entre enum e classes seladas
No Kotlin, as classes seladas podem ser consideradas como classes Enum turbinadas. Classes seladas permitem que criemos instâncias com diferentes tipos, ao contrário dos Enums que nos restringem a usar o mesmo tipo para todas as constantes enum. O seguinte não é possível em classes Enum.
enum class Months(string: String){
January("Jan"), February(2),
}
Classes Enum permitem apenas um único tipo para todas as constantes. Aqui é onde as classes seladas vêm ao nosso resgate ao permitir múltiplas instâncias.
sealed class Months {
class January(var shortHand: String) : Months()
class February(var number: Int) : Months()
class March(var shortHand: String, var number: Int) : Months()
}
Como você pode usar esse recurso de classes seladas em seus projetos? Em um aplicativo de feed de notícias, você pode criar três tipos de classe diferentes para postagens de Status, Imagem e Vídeo, como mostrado abaixo.
sealed class Post
{
class Status(var text: String) : Post()
class Image(var url: String, var caption: String) : Post()
class Video(var url: String, var timeDuration: Int, var encoding: String): Post()
}
Isso não é possível com classes Enum.
Classes seladas e when
As classes seladas são comumente usadas com instruções when
, já que cada uma das subclasses e seus tipos atuam como um caso. Além disso, sabemos que a classe Selada limita os tipos. Portanto, a parte else
da instrução when
pode ser facilmente removida. O exemplo a seguir demonstra o mesmo.
sealed class Shape{
class Circle(var radius: Float): Shape()
class Square(var length: Int): Shape()
class Rectangle(var length: Int, var breadth: Int): Shape()
}
fun eval(e: Shape) =
when (e) {
is Shape.Circle -> println("Circle area is ${3.14*e.radius*e.radius}")
is Shape.Square -> println("Square area is ${e.length*e.length}")
is Shape.Rectangle -> println("Rectagle area is ${e.length*e.breadth}")
}
Vamos executar a função eval
em nossa função main
conforme mostrado abaixo.
fun main(args: Array) {
var circle = Shape.Circle(4.5f)
var square = Shape.Square(4)
var rectangle = Shape.Rectangle(4,5)
eval(circle)
eval(square)
eval(rectangle)
//eval(x) //erro de compilação em tempo de execução.
}
//O seguinte é impresso no console:
//A área do círculo é 63.585
//A área do quadrado é 16
//A área do retângulo é 20
Nota: O modificador is
verifica se a classe é do tipo seguinte. O modificador is
é necessário apenas para classes. Não com objetos Kotlin, como mostrado abaixo:
sealed class Shape{
class Circle(var radius: Float): Shape()
class Square(var length: Int): Shape()
object Rectangle: Shape()
{
var length: Int = 0
var breadth : Int = 0
}
}
fun eval(e: Shape) =
when (e) {
is Shape.Circle -> println("Circle area is ${3.14*e.radius*e.radius}")
is Shape.Square -> println("Square area is ${e.length*e.length}")
Shape.Rectangle -> println("Rectangle area is ${Shape.Rectangle.length*Shape.Rectangle.breadth}")
}
Isso encerra o tutorial da classe selada do Kotlin. Referências: Documentação do Kotlin
Source:
https://www.digitalocean.com/community/tutorials/kotlin-sealed-class