Sobes.tech
Junior

Como é organizada a herança e o polimorfismo em Kotlin?

sobes.tech IA

Resposta da IA

Em Kotlin, a herança é implementada através de mecanismos de classes e interfaces. As classes podem herdar apenas de uma outra classe (herança simples), mas podem implementar múltiplas interfaces.

Por padrão, todas as classes em Kotlin são 'final', ou seja, não podem ser herdadas. Para permitir herança, uma classe deve ser explicitamente marcada com a palavra-chave open.

Herança de classes:

open class Shape { // Classe base, marcada como open
    open fun draw() { // Método que pode ser sobrescrito
        println("Desenhando uma forma")
    }
}

class Circle : Shape() { // Herança de Shape
    override fun draw() { // Sobrescreve o método
        println("Desenhando um círculo")
    }
}

No construtor da classe filha, é necessário chamar explicitamente ou implicitamente o construtor da classe base.

Interfaces:

As interfaces em Kotlin são semelhantes às do Java 8 e podem conter métodos abstratos e métodos com implementação. As classes podem implementar uma ou várias interfaces.

interface Drawable {
    fun draw() // Método abstrato
    fun description() { // Método com implementação padrão
        println("Este é um objeto desenhável")
    }
}

class Square : Drawable {
    override fun draw() { // Implementação do método abstrato
        println("Desenhando um quadrado")
    }
    // description() pode ser sobrescrito, mas não é obrigatório
}

Polimorfismo:

O polimorfismo em Kotlin é alcançado através da capacidade de trabalhar com objetos de diferentes classes através de um tipo base comum (classe ou interface). Isso permite chamar métodos específicos do tipo real do objeto em tempo de execução.

fun render(drawable: Drawable) {
    drawable.draw() // Chamada do método draw() dependendo do tipo real do objeto
    drawable.description()
}

fun main() {
    val circle: Shape = Circle() // Objeto Circle tratado como Shape
    circle.draw() // Chamada de draw() de Circle devido ao polimorfismo

    val square: Drawable = Square() // Objeto Square tratado como Drawable
    render(square) // Chamada de draw() e description() de Square
}

Neste exemplo, render trabalha com qualquer objeto que implemente Drawable. A chamada a drawable.draw() executará a implementação do método draw para o tipo específico do objeto (Square neste caso).

Diferenças entre herança de classes e implementação de interfaces:

  • Herança de classe: Estabelece a relação "é um" (is-a). A classe filha herda o estado e comportamento da classe base.
  • Implementação de interface: Define uma "capacidade" ou "contrato". A classe promete fornecer a implementação de todos os métodos abstratos da interface.

Tabela comparativa:

Característica Herança de classe Implementação de interface
Tipo de relação é-a Capacidade / Contrato
Múltiplas Única Múltipla
Estado Herda o estado da classe base Não herda estado
Implementação de métodos Pode conter implementação Pode conter implementação por padrão (a partir do Java 8)