Clase Kotlin – Constructor Kotlin

En este tutorial, estaremos discutiendo los conceptos de Programación Orientada a Objetos de Kotlin. Hablaremos en detalle sobre la Clase Kotlin. También veremos constructores de Kotlin, modificadores de acceso y clases abstractas.

Clase Kotlin

Una clase es un modelo definido que agrupa funciones y propiedades. Las clases en Kotlin se definen utilizando la palabra clave class seguida del nombre de la clase. El cuerpo va dentro de las llaves.

class FirstClass {
}

Se instancia una instancia de la clase de la siguiente manera:

val firstClass =  FirstClass()
var new = FirstClass() //here new is the name of the var.

A diferencia de Java, new no es una palabra clave en Kotlin. Las clases por defecto son final en Kotlin. Entonces, el equivalente de las definiciones anteriores en Java se vería algo como esto:

public final class FirstClass {
}

Por lo tanto, por defecto las clases en Kotlin no son heredables. Para hacer una clase no final, debemos agregar la palabra clave open.

open class Me{
}

La anotación open permite que otros hereden de esta clase.

Ejemplo de Clase Kotlin

Vamos a crear una clase con algunas funciones y una propiedad. Veremos cómo acceder a las funciones y propiedades de esa clase. Además, veremos cómo establecer las propiedades de miembro.

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.

}

La función main pertenece a la clase Test.kt. Para acceder a miembros y funciones, necesitamos usar el operador punto. Una propiedad val no se puede establecer nuevamente utilizando un operador punto.

Inicialización en Kotlin

El bloque de inicialización en Kotlin se define como se muestra a continuación.

class User {
    
    init{
        print("Class instance is initialised.")
    }

    var loggedIn: Boolean = false
    val cantChangeValue = "Hi"

    fun logOn() {
        loggedIn = true
    }

    fun logOff() {
        loggedIn = false
    }
}

El código dentro del bloque init es el primero en ejecutarse cuando se instancia la clase. El bloque init se ejecuta cada vez que se instancia la clase, con cualquier tipo de constructor, como veremos a continuación. Se pueden escribir varios bloques de inicialización en una clase. Se ejecutarán secuencialmente como se muestra a continuación.

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")
}

//Lo siguiente se imprime en la consola de registro. 
//Primer bloque de inicialización que imprime Kotlin. 
//Segundo bloque de inicialización que imprime 6. 

Las clases en Kotlin permiten imprimir propiedades en la declaración misma mediante la función also, como se muestra a continuación.

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")
}

//Lo siguiente se imprime. 
//Primera propiedad: Kotlin. 
//Primer bloque de inicialización que imprime Kotlin. 
//Segunda propiedad: 6. 
//Segundo bloque de inicialización que imprime 6.

Constructor de Kotlin

Los constructores en Kotlin son funciones miembro especiales que se utilizan para inicializar propiedades. Los constructores en Kotlin se escriben y estructuran de manera diferente en comparación con Java. Por defecto, una clase tiene un constructor vacío como se muestra a continuación:

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 //no se compilará. age es val
    println("${student.name} age is ${student.age}")

}

//Lo siguiente se imprime en la consola:
//Anupam Chugh edad es 24
//Tu edad es 24

Constructores Primarios

Los constructores primarios en Kotlin se definen en el encabezado de la clase misma como se muestra a continuación.

class User(var name: String, var isAdmin: Boolean) {

    init {
        name = name + " @ JournalDev.com"
        println("Author Name is $name. Is Admin? $isAdmin")
    }
}

La definición de los constructores primarios va dentro del encabezado de la clase. Hemos definido los tipos de propiedad (val/var) en el propio constructor. Nota: A menos que se indique como un var, por defecto, los argumentos del constructor son val.

class User(name: String, isAdmin: Boolean)

En el código anterior, tanto el nombre como isAdmin no pueden ser reasignados. Alternativamente, también podemos asignar los argumentos del constructor a las propiedades miembro en la clase como se muestra a continuación.

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)
}

//Lo siguiente se imprime en la consola de registro.
//Nombre del autor es Anupam. ¿Es administrador? falso
//Nombre del autor es Pankaj. ¿Es administrador? verdadero

Valores Predeterminados del Constructor de Kotlin

Kotlin nos permite especificar valores predeterminados en el propio constructor como se muestra a continuación.

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")
}

//Lo siguiente se imprime en la consola:
//El autor Anupam escribe en JournalDev
//El autor Anupam escribe en JournalDev.com
//El autor Pankaj escribe en JournalDev
//El autor Pankaj escribe en JournalDev.com

Constructores Secundarios

Los constructores secundarios se escriben dentro del cuerpo de la clase prefijándolos con la palabra clave constructor. El siguiente ejemplo demuestra lo mismo.

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()
}

//Lo siguiente se imprime en la consola.
//El nombre es Anupam y la edad es 24

El uso más común de los constructores secundarios ocurre en subclases cuando necesitas inicializar la clase de diferentes maneras. Si la clase contiene un constructor primario, el constructor secundario debe hacer referencia a él en su declaración. La declaración se realiza utilizando la palabra clave 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")
    }
}

//Lo siguiente se imprime en la consola de registro:
//El nombre es Anupam y la edad es 24
//El nombre es Anupam y la edad es 24 Skill is Kotlin

init bloque se utiliza para inicializar la propiedad del miembro skill. El constructor secundario delega al constructor primario usando : this.

Obtención y establecimiento personalizados

Hasta ahora hemos accedido y modificado propiedades en una clase usando el operador de punto en la instancia de la clase. Usemos la sintaxis de set y get para ver cómo podemos personalizar el acceso.

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"


}

Lo siguiente se imprime en la consola de registro:

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)

La variable field en el setter guarda el valor anterior. Agreguemos un 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)

}

//Lo siguiente se imprime:
//Clases de Kotlin
//Clases de datos de Kotlin, nuestro próximo tutorial

capitalize() capitaliza la primera letra de la cadena. Nota: si la propiedad es un val, el método set no se compilará.

Modificador de visibilidad en Kotlin

  • Público: Cualquier clase, función, propiedad, interfaz u objeto que tenga este modificador es visible y se puede acceder desde cualquier lugar.
  • Privado: Una clase/función definida con este modificador solo puede ser accedida dentro del mismo archivo. Un miembro/propiedad en una clase/función con este modificador solo puede ser accedido dentro de ese bloque.
  • Protegido: Este modificador es igual que privado, excepto que permite visibilidad y acceso dentro de subclases.
  • Interno: Una clase/interface/función con este modificador es accesible solo dentro del mismo módulo.

Los modificadores de visibilidad también son aplicables a los constructores. Asignar un modificador a un constructor primario requiere que especifiquemos la palabra clave constructor junto al constructor en el encabezado de la clase.

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
//Nombre es Anupam y Edad es 24 Habilidad es Kotlin

Los constructores privados no pueden ser llamados fuera de la clase. En el código anterior, podemos instanciar la clase en una función diferente solo usando el constructor secundario.

Clase Abstracta Kotlin

Al igual que en Java, la palabra clave abstract se utiliza para declarar clases abstractas en Kotlin. Una clase abstracta no puede ser instanciada. Sin embargo, puede ser heredada por subclases. Por defecto, los miembros de una clase abstracta son no abstractos a menos que se especifique lo contrario.

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()

}

//Lo siguiente se imprime en la consola.
//Clase Abstracta. Bloque init. El nombre de la persona es Anupam
//Clase no abstracta. La Edad es 24

Nota: Las clases abstractas son, por defecto, open. Por lo tanto, no es necesario agregar un modificador open para permitir la subclasificación. La palabra clave override se utiliza para sobrescribir un método en la subclase. Hemos cubierto los conceptos básicos de las clases de Kotlin en este tutorial. Aún hay mucho más, como las Clases de Datos, Clases Selladas, Herencia, etc. Los cubriremos en los próximos tutoriales. Referencias: Documentación de Kotlin

Source:
https://www.digitalocean.com/community/tutorials/kotlin-class-constructor