O que é Interface em Kotlin?

Uma interface em Kotlin define um contrato que classes devem seguir. Ela declara quais funções e propriedades uma classe precisa ter, mas sem obrigar uma implementação específica. Diferente de classes abstratas, uma classe pode implementar várias interfaces.

Sintaxe básica

interface Autenticavel {
    fun autenticar(senha: String): Boolean
}

class Usuario(val nome: String, private val senhaHash: String) : Autenticavel {
    override fun autenticar(senha: String): Boolean {
        return senha == senhaHash
    }
}

fun main() {
    val user = Usuario("Karina", "abc123")
    println(user.autenticar("abc123")) // true
    println(user.autenticar("errada")) // false
}

Métodos com implementação padrão

Em Kotlin, interfaces podem ter métodos com corpo — os famosos default methods:

interface Logavel {
    val tag: String
        get() = this::class.simpleName ?: "Desconhecido"

    fun log(mensagem: String) {
        println("[$tag] $mensagem")
    }
}

class Servico : Logavel

fun main() {
    val servico = Servico()
    servico.log("Iniciando processamento")
    // [Servico] Iniciando processamento
}

Múltiplas interfaces

interface Imprimivel {
    fun imprimir()
}

interface Exportavel {
    fun exportar(): String
}

class Relatorio(val titulo: String) : Imprimivel, Exportavel {
    override fun imprimir() {
        println("Imprimindo: $titulo")
    }

    override fun exportar(): String {
        return "PDF: $titulo"
    }
}

fun main() {
    val relatorio = Relatorio("Vendas Q1")
    relatorio.imprimir()
    println(relatorio.exportar())
}

Resolvendo conflitos

Quando duas interfaces têm o mesmo método com implementação padrão, você precisa resolver o conflito manualmente:

interface A {
    fun saudacao() = "Olá de A"
}

interface B {
    fun saudacao() = "Olá de B"
}

class C : A, B {
    override fun saudacao(): String {
        return "${super<A>.saudacao()} e ${super<B>.saudacao()}"
    }
}

Quando usar interface vs abstract class?

Use interface quando quiser definir um contrato que múltiplas classes podem adotar. Use abstract class quando precisar de estado compartilhado (campos com valores) ou construtores. Interfaces são mais flexíveis e promovem um design mais desacoplado.