As classes em Kotlin são declaradas usando a palavra-chave class
:
class Person {
//...
}
A declaração de classe consiste no nome da classe, no cabeçalho da classe (especificando seus parâmetros de tipo, o construtor primário e algumas outras coisas) e o corpo da classe entre chaves. Tanto o cabeçalho quanto o corpo são opcionais, se a classe não tiver corpo, as chaves podem ser omitidas:
class Person
Propriedades em classes Kotlin podem ser declaradas como mutáveis, usando a palavra-chave var
,
ou como somente leitura, usando a palavra-chave val
:
class Person(val age: Int, val name: String)
Para declarar uma instância dessa classe, basta fazer:
val person = Person(25, "Gustavo")
ou usando argumentos nomeados:
val person = Person(age = 25, name = "Gustavo")
Por padrão, toda classe que criamos não é aberta para ser herdada por outra,
então, precisamos usar a palavra-chave open
para que a herança seja permitida:
open class Person(val age: Int, val name: String)
class Driver(age: Int, name: String, val license: String) : Person(age, name)
Você pode testar esse código online.
Não é incomum criar classes cujo objetivo principal seja armazenar dados, como,
DTOs.
Em Kotlin, elas são chamadas classes de dados sendo declaradas usando a palavra-chave data
:
data class Person(val age: Int, val name: String)
O compilador deriva automaticamente os seguintes membros de todas as propriedades declaradas no construtor primário:
equals
, hashCode
, toString
e copy
.
Para garantir consistência e comportamento significativo do código gerado, as classes de dados devem atender aos seguintes requisitos:
- O construtor primário precisa ter pelo menos um parâmetro.
- Todos os parâmetros do construtor primário precisam ser marcados como
val
ouvar
. - As classes de dados não podem ser abstratas, abertas, seladas ou internas.
Para declarar uma instância dessa classe, basta fazer:
val person = Person(age = 25, name = "Gustavo")
ou usando argumentos nomeados:
val person = Person(age = 25, name = "Gustavo")
Você pode testar esse código online.
As classes do tipo enum em Kotlin são declaradas usando a palavra-chave enum
:
enum class Type {
CUSTOMER,
EMPLOYEE
}
Cada constante enum é um objeto. As constantes de enumeração são separadas por vírgulas. Como cada enum é uma instância da classe enum, ele pode ser inicializado como:
enum class Type(val value: Int) {
CUSTOMER(value = 1),
EMPLOYEE(value = 2)
}
Você pode testar esse código online.
As constantes de enumeração podem declarar suas próprias classes anônimas com seus métodos correspondentes, bem como substituir os métodos-base:
enum class Type {
CUSTOMER {
override fun register() = CUSTOMER
},
EMPLOYEE {
override fun register() = EMPLOYEE
};
abstract fun register(): Type
}
Você pode testar esse código online.
Nota
Uma classe enum pode implementar uma interface, mas não pode derivar de uma classe, fornecendo uma implementação comum de membros de interface para todas as entradas ou implementações separadas para cada entrada dentro de sua classe anônima. Isso é feito adicionando as interfaces que você deseja implementar à declaração da classe enum.
As classes em Kotlin podem ser abstratas, basta declará-las usando a palavra-chave abstract
:
abstract class Customer {
abstract fun register()
}
E na classe que você deseja que estenda a classe abstrata, basta fazer:
class Person(val age: Int, val name: String) : Customer() {
override fun register() {
val template = "Registrado %s, %s anos."
println(template.format(name, age))
}
}
Você pode testar esse código online.
Em Kotlin podemos fazer a declaração de objetos que fazem a implementação do
padrão singleton, basta declarar a palavra-chave object
:
object PalindromeChecker {
fun isPalindrome(word: String): Boolean {
val reversedWord = word.reversed()
return word == reversedWord
}
}
Para se referir ao objeto, use seu nome diretamente:
PalindromeChecker.isPalindrome(word = "level")
Você pode testar esse código online.
O Kotlin também nos permite criar o que é chamado companion object, um objeto que fica em uma classe. Para isso,
precisamos usar a palavra-chave companion object
:
class Person(val age: Int, val name: String) {
companion object {
fun newborn(name: String) = Person(age = 0, name = name)
}
}
O companion object nos dá a possibilidade de utilizarmos o método newborn
através da classe Person
sem precisarmos
criar uma instância da mesma:
val person = Person.newborn(name = "Gustavo")
Você pode testar esse código online
Interfaces em Kotlin podem conter declarações de métodos abstratos, bem como implementações de métodos. O que as torna diferentes das classes abstratas é que as interfaces não podem armazenar o estado. Eles podem ter propriedades, mas elas precisam ser abstratas ou fornecer implementações de acessador.
Uma interface é definida usando a palavra-chave interface
:
interface Customer {
fun register()
}
Uma interface pode derivar de outras interfaces, o que significa que ela pode fornecer implementações para seus membros e declarar novas funções e propriedades:
interface PremiumCustomer : Customer
Você pode declarar propriedades em interfaces. Uma propriedade declarada em uma interface pode ser abstrata ou fornecer implementações para acessadores:
interface PremiumCustomer : Customer {
val minimumLimit: Double
}
Você pode testar esse código online.
O padrão Delegation provou ser uma boa alternativa para a herança de
implementação, e o Kotlin o suporta nativamente. Uma classe Person
pode implementar uma interface Customer
delegando todos os seus membros públicos a um
objeto especificado:
interface Customer {
fun register()
}
class CustomerAdapter(private val name: String) : Customer {
override fun register() {
val template = "Registrado %s."
println(template.format(name))
}
}
class Person(customer: Customer) : Customer by customer
Você pode testar esse código online.
Ir para expressões condicionais.