O que é class em Kotlin?
A palavra-chave class em Kotlin é usada para definir classes, que sao a base da programacao orientada a objetos. Uma classe funciona como um molde para criar objetos, agrupando propriedades e comportamentos relacionados.
Se você vem do Java, vai adorar a quantidade de código que Kotlin elimina. O que levaria dezenas de linhas em Java, em Kotlin fica resolvido em poucas.
Pense em uma classe como a receita de um bolo: ela descreve os ingredientes (propriedades) é o modo de preparo (métodos). Cada bolo que você faz seguindo a receita é uma instancia daquela classe. A receita em si não e comestivel, mas cada bolo criado a partir dela e.
Sintaxe básica
class Pessoa(val nome: String, var idade: Int)
fun main() {
val pessoa = Pessoa("Rafael", 28)
println("${pessoa.nome} tem ${pessoa.idade} anos.")
pessoa.idade = 29 // idade e var, pode alterar
}
O construtor primario já vai direto na declaracao da classe, entre parenteses. As propriedades val e var sao declaradas ali mesmo – sem precisar de campos separados, getters ou setters.
Metodos e inicialização
Voce pode adicionar funções dentro da classe e usar o bloco init para lógica de inicialização:
class ContaBancaria(val titular: String, var saldo: Double) {
init {
require(saldo >= 0) { "Saldo inicial nao pode ser negativo" }
}
fun depositar(valor: Double) {
saldo += valor
println("Deposito de R$ $valor realizado. Saldo: R$ $saldo")
}
fun sacar(valor: Double) {
if (valor <= saldo) {
saldo -= valor
println("Saque de R$ $valor realizado. Saldo: R$ $saldo")
} else {
println("Saldo insuficiente!")
}
}
}
Construtores secundarios
Alem do construtor primario, da pra ter construtores secundarios usando constructor:
class Produto(val nome: String, val preco: Double) {
constructor(nome: String) : this(nome, 0.0)
}
Heranca
Por padrão, classes em Kotlin sao final – não podem ser herdadas. Para permitir heranca, e preciso usar o modificador open:
open class Animal(val nome: String)
class Cachorro(nome: String, val raca: String) : Animal(nome)
Classes em Kotlin sao diretas ao ponto. Menos boilerplate, mais produtividade.
Classe com propriedades computadas e backing field
Nem toda propriedade precisa ser um simples campo armazenado. Voce pode criar propriedades com getters e setters customizados:
class Temperatura(celsius: Double) {
var celsius: Double = celsius
set(valor) {
require(valor >= -273.15) { "Temperatura abaixo do zero absoluto" }
field = valor
}
val fahrenheit: Double
get() = celsius * 9.0 / 5.0 + 32
val kelvin: Double
get() = celsius + 273.15
override fun toString(): String {
return "%.1f C / %.1f F / %.1f K".format(celsius, fahrenheit, kelvin)
}
}
fun main() {
val temp = Temperatura(25.0)
println(temp) // 25.0 C / 77.0 F / 298.1 K
temp.celsius = 100.0
println(temp) // 100.0 C / 212.0 F / 373.1 K
}
Classe com companion object e factory methods
O companion object permite criar membros associados a classe (similares a membros estaticos do Java):
class Conexao private constructor(
val host: String,
val porta: Int,
val usarSsl: Boolean
) {
companion object {
fun producao() = Conexao("api.exemplo.com", 443, true)
fun desenvolvimento() = Conexao("localhost", 8080, false)
fun deTeste() = Conexao("localhost", 9090, false)
}
fun url(): String {
val protocolo = if (usarSsl) "https" else "http"
return "$protocolo://$host:$porta"
}
}
fun main() {
val conn = Conexao.producao()
println(conn.url()) // https://api.exemplo.com:443
val dev = Conexao.desenvolvimento()
println(dev.url()) // http://localhost:8080
}
Classe com delegacao de interface
Kotlin suporta delegacao nativamente, permitindo que uma classe delegue a implementação de uma interface para outro objeto:
interface Logger {
fun log(mensagem: String)
}
class ConsoleLogger : Logger {
override fun log(mensagem: String) {
println("[LOG] $mensagem")
}
}
class Servico(logger: Logger) : Logger by logger {
fun executar() {
log("Servico iniciado") // delegado ao ConsoleLogger
// logica do servico
log("Servico finalizado")
}
}
Casos de Uso no Mundo Real
- Modelagem de dominio: classes representam entidades do negócio como
Pedido,Cliente,Produto. Para entidades focadas em dados, considere data classes. - Servicos e controladores: no Spring Boot e Ktor, classes encapsulam a lógica de negocios e endpoints da API.
- ViewModels no Android: classes que estendem
ViewModelgerenciam o estado da UI e sobrevivem a mudancas de configuração. - Wrappers e adaptadores: classes que encapsulam APIs externas, oferecendo uma interface mais limpa para o restante do código.
- Builders: classes que implementam o padrão builder para construcao de objetos complexos, especialmente úteis em DSLs Kotlin.
Boas Praticas
- Prefira data class quando a classe serve principalmente para armazenar dados, pois ela gera
equals(),hashCode(),toString()ecopy()automaticamente. - Use val para propriedades sempre que possível, favorecendo imutabilidade.
- Mantenha classes pequenas e focadas em uma única responsabilidade. Se uma classe tem muitos métodos, considere dividi-la.
- Aproveite valores padrão em parametros do construtor em vez de criar múltiplos construtores secundarios.
- Use
private constructorcom factory methods no companion object quando precisar controlar como instancias sao criadas.
Erros Comuns
- Esquecer
openpara heranca: diferente do Java, classes Kotlin saofinalpor padrão. Tentar herdar de uma classe semopencausa erro de compilação. - Confundir
valevarno construtor:valcria uma propriedade somente leitura,varpermite alteracao. Parametros semval/varno construtor primario sao apenas parametros, não propriedades da classe. - Bloco
initcom lógica pesada: o blocoinitroda toda vez que a classe e instanciada. Evite colocar operações de rede, leitura de arquivos ou lógica demorada nele. - Nao usar data class quando apropriado: criar uma classe normal e implementar
equals(),hashCode()etoString()manualmente quando uma data class faria tudo automaticamente.
Perguntas Frequentes
Qual a diferenca entre class e data class?
Uma class normal não gera automaticamente equals(), hashCode(), toString() nem copy(). Uma data class gera todos esses métodos com base nas propriedades do construtor primario. Use data class para objetos que representam dados.
Posso ter uma classe sem corpo?
Sim. class Vazia e perfeitamente válido em Kotlin. Tambem e possível ter uma classe só com construtor: class Ponto(val x: Int, val y: Int).
Qual a diferenca entre class e object?
class e um molde para criar múltiplas instancias. object cria uma única instancia (singleton). Use object quando você precisa de apenas uma instancia em todo o aplicativo.
Quando usar abstract class vs interface? Use abstract class quando subclasses compartilham estado (propriedades com valor) e lógica de construtor. Use interface quando você precisa apenas de um contrato, especialmente se a classe já herda de outra (Kotlin não suporta heranca multipla de classes, mas suporta múltiplas interfaces).