Neste tutorial, estaremos discutindo os conceitos de Programação Orientada a Objetos em Kotlin. Vamos abordar detalhadamente a classe Kotlin. Também vamos analisar construtores Kotlin, modificadores de acesso e classe abstrata.
Classe Kotlin
Uma classe é um modelo definido que agrupa funções e propriedades. As classes em Kotlin são definidas usando a palavra-chave
class
seguida pelo nome da classe. O corpo vai dentro das chaves.
class FirstClass {
}
Uma instância da classe é instanciada da seguinte maneira:
val firstClass = FirstClass()
var new = FirstClass() //here new is the name of the var.
Contrariamente ao Java, new
não é uma palavra-chave em Kotlin. As classes por padrão são final em Kotlin. Portanto, o equivalente das definições acima em Java seria algo assim:
public final class FirstClass {
}
Portanto, por padrão, as classes em Kotlin não são herdáveis. Para tornar uma classe não final, precisamos anexar a palavra-chave open
.
open class Me{
}
A anotação open
permite que outros herdem dessa classe.
Exemplo de Classe Kotlin
Vamos criar uma classe com algumas funções e uma propriedade. Veremos como acessar as funções e propriedades dessa classe. Além disso, veremos como definir as propriedades de membro.
class User {
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
fun main(args: Array<String>) {
val user = User()
println(user.loggedIn) //false
user.logOn()
println(user.loggedIn) //true
user.logOff()
println(user.loggedIn) //false
user.cantChangeValue = "Hey" //won't compile. Can't modify a final variable.
}
A função main
pertence à classe Test.kt
. Para acessar membros e funções, precisamos usar o operador ponto. Uma propriedade val
não pode ser definida novamente usando o operador ponto.
Kotlin init
O bloco init do Kotlin é definido como mostrado abaixo.
class User {
init{
print("Class instance is initialised.")
}
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
O código dentro do bloco init
é o primeiro a ser executado quando a classe é instanciada. O bloco init
é executado toda vez que a classe é instanciada, com qualquer tipo de construtor, como veremos a seguir. Múltiplos blocos inicializadores podem ser escritos em uma classe. Eles serão executados sequencialmente, como mostrado abaixo.
class MultiInit(name: String) {
init {
println("First initializer block that prints ${name}")
}
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array) {
var multiInit = MultiInit("Kotlin")
}
//O seguinte é impresso no console de log.
//Primeiro bloco inicializador que imprime Kotlin
//Segundo bloco inicializador que imprime 6
As classes Kotlin permitem imprimir propriedades na própria declaração usando a função also
, conforme mostrado abaixo.
class MultiInit(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First initializer block that prints ${name}")
}
val secondProperty = "Second property: ${name.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array) {
var multiInit = MultiInit("Kotlin")
}
//O seguinte é impresso.
//Primeira propriedade: Kotlin
//Primeiro bloco inicializador que imprime Kotlin
//Segunda propriedade: 6
//Segundo bloco inicializador que imprime 6
Construtor Kotlin
Construtores em Kotlin são funções de membro especiais que são usadas para inicializar propriedades. Os construtores em Kotlin são escritos e estruturados de forma diferente em comparação com Java. Por padrão, uma classe tem um construtor vazio, como mostrado abaixo:
class Student {
var name: String
val age : Int
init {
name = "Anupam"
age = 24
}
init {
name = "Anupam Chugh"
//age = 26
}
}
fun main(args: Array) {
val student = Student()
println("${student.name} age is ${student.age}")
student.name = "Your"
//student.age = 26 //não irá compilar. age é val
println("${student.name} age is ${student.age}")
}
//A seguinte saída é impressa no console:
//Anupam Chugh idade é 24
//Sua idade é 24
Construtores Primários
Construtores primários em Kotlin são definidos no cabeçalho da classe, como mostrado abaixo.
class User(var name: String, var isAdmin: Boolean) {
init {
name = name + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $isAdmin")
}
}
A definição dos construtores primários vai dentro do cabeçalho da classe. Nós definimos os tipos de propriedades (val/var) no próprio construtor. Observação: A menos que declarado como um var
, por padrão, os argumentos do construtor são val
.
class User(name: String, isAdmin: Boolean)
No código acima, tanto o nome quanto o isAdmin não podem ser reatribuídos. Alternativamente, também podemos atribuir os argumentos do construtor às propriedades de membro na classe, como mostrado abaixo.
class User(name: String, val isAdmin: Boolean) {
var username = name
val _isAdmin = isAdmin
init {
username= username + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $_isAdmin")
}
}
fun main(args: Array) {
var user = User("Anupam",false)
user.isAdmin = true //won't compile since isAdmin is val
user._isAdmin = true //won't compile. Same reason.
user = User("Pankaj",true)
}
//A seguinte saída é impressa no console de log.
//Nome do autor é Anupam. É administrador? falso
//Nome do autor é Pankaj. É administrador? verdadeiro
Valores Padrão do Construtor Kotlin
O Kotlin nos permite especificar valores padrão no próprio construtor, como mostrado abaixo.
class User(name: String, var website: String = "JournalDev") {
init {
println("Author $name writes at $website")
}
init {
website = website + ".com"
println("Author $name writes at $website")
}
}
fun main(args: Array) {
var user = User("Anupam","JournalDev")
user = User("Pankaj","JournalDev")
}
//O seguinte é impresso no console:
//O autor Anupam escreve no JournalDev
//O autor Anupam escreve no JournalDev.com
//O autor Pankaj escreve no JournalDev
//O autor Pankaj escreve no JournalDev.com
Construtores Secundários
Os construtores secundários são escritos dentro do corpo da classe prefixando com a palavra-chave constructor
. O exemplo a seguir demonstra o mesmo.
class Student {
var name: String
val age : Int
constructor(name: String, age: Int)
{
this.name = name
this.age = age
}
fun printDetails()
{
println("Name is $name and Age is $age")
}
}
fun main(args: Array) {
var student = Student("Anupam", 24)
student.printDetails()
}
//O seguinte é impresso no console.
//Nome é Anupam e Idade é 24
A utilização mais comum dos construtores secundários ocorre em subclasses quando é necessário inicializar a classe de maneiras diferentes. Se a classe contém um construtor primário, o construtor secundário deve se referir a ele em sua declaração. A declaração é feita usando a palavra-chave this
.
class Student(var name: String, val age: Int) {
var skill: String
init {
skill = "NA"
}
constructor(name: String, age: Int, skill: String) : this(name, age) {
this.skill = skill
}
fun printDetails() {
if (skill.equals("NA"))
println("Name is $name and Age is $age")
else
println("Name is $name and Age is $age Skill is $skill")
}
}
//O seguinte é impresso no console de log:
//Nome é Anupam e Idade é 24
//Nome é Anupam e Idade é 24 Skill is Kotlin
O bloco init
é usado para inicializar a propriedade de membro skill
. O construtor secundário delega para o construtor primário usando : this
.
Getters e Setters Personalizados
Até agora, acessamos e modificamos propriedades em uma classe usando o operador de ponto na instância da classe. Vamos usar a sintaxe set
e get
para ver como podemos personalizar o acesso.
class Name{
var post: String = "default"
set(value) {if(!post.isNotEmpty()) {
throw IllegalArgumentException(" Enter a valid name")
}
field = value
print(value)
}
}
fun main(args: Array<String>) {
var name = Name()
name.post = "Kotlin Classes"
name.post = ""
name.post = "Kotlin Data Classes Our Next Tutorial"
}
O seguinte é impresso no console de log:
Kotlin Classes
Exception in thread "main" java.lang.IllegalArgumentException: Enter a valid name
at Name.setPost(Test.kt:16)
at TestKt.main(Test.kt:78)
A variável field
no setter salva o valor anterior. Vamos adicionar um getter.
class Name{
var post: String = "default"
set(value) {if(!post.isNotEmpty()) {
throw IllegalArgumentException(" Enter a valid name")
}
field = value
}
get() {
return field.capitalize()
}
}
fun main(args: Array) {
var name = Name()
name.post = "kotlin classes"
println(name.post)
name.post = "kotlin data Classes our next Tutorial"
println(name.post)
}
//O seguinte é impresso:
//Classes Kotlin
//Classes de Dados Kotlin, nosso próximo Tutorial
capitalize()
capitaliza a primeira letra da string. Observação: se a propriedade for um val
, o método set
não compilará.
Modificador de Visibilidade Kotlin
- Público : Qualquer classe, função, propriedade, interface ou objeto que tenha este modificador é visível e pode ser acessado de qualquer lugar.
- Privado: Uma classe/função definida com esse modificador só pode ser acessada dentro do mesmo arquivo. Um membro/propriedade em uma classe/função com esse modificador só pode ser acessado dentro desse bloco.
- Protegido: Este modificador é igual ao privado, exceto que ele permite visibilidade e acesso dentro de subclasses.
- Interno: Uma classe/interface/função com esse modificador é acessível apenas dentro do mesmo módulo.
Os modificadores de visibilidade também são aplicáveis aos construtores. Atribuir um modificador a um Construtor Primário requer que especifiquemos a palavra-chave constructor
junto ao construtor no cabeçalho da classe.
class Student private constructor (var name: String, val age: Int) {
var skill: String
init {
skill = "NA"
}
constructor(name: String, age: Int, skill: String) : this(name, age) {
this.skill = skill
}
fun printDetails() {
if (skill.equals("NA"))
println("Name is $name and Age is $age")
else
println("Name is $name and Age is $age Skill is $skill")
}
}
fun main(args: Array) {
var student = Student("Anupam",24,"Kotlin")
student.printDetails()
}
//prints
//Nome é Anupam e Idade é 24 Habilidade é Kotlin
Construtores privados não podem ser chamados fora da classe. No código acima, podemos instanciar a classe em uma função diferente apenas usando o construtor secundário.
Classe Abstrata Kotlin
Assim como em Java, a palavra-chave abstract
é usada para declarar classes abstratas em Kotlin. Uma classe abstrata não pode ser instanciada. No entanto, pode ser herdada por subclasses. Por padrão, os membros de uma classe abstrata são não abstratos, a menos que seja declarado o contrário.
abstract class Person(name: String) {
init {
println("Abstract Class. init block. Person name is $name")
}
abstract fun displayAge()
}
class Teacher(name: String): Person(name) {
var age : Int
init {
age = 24
}
override fun displayAge() {
println("Non-abstract class displayAge function overridden. Age is $age")
}
}
fun main(args: Array) {
val person = Teacher("Anupam")
person.displayAge()
}
//O seguinte é impresso no console.
//Classe Abstrata. bloco init. O nome da pessoa é Anupam
//Classe não abstrata. Idade é 24
Nota: As classes abstratas são, por padrão, open
. Portanto, adicionar um modificador open
para permitir a herança não é necessário. A palavra-chave override
é usada para substituir um método na subclasse. Cobrimos o básico das classes em Kotlin neste tutorial. Ainda há muito mais, como Classes de Dados, Classes Seladas, Herança, etc. Vamos abordá-los nos próximos tutoriais. Referências: Documentação do Kotlin
Source:
https://www.digitalocean.com/community/tutorials/kotlin-class-constructor