Kotlin: Programación Orientada a Objetos
Kotlin implementa Programación Orientada a Objetos con enfoques modernos. Domina clases, objetos, herencia, polimorfismo y encapsulación en Kotlin.
Aprende Kotlin GRATIS y certifícateLa programación orientada a objetos (POO) es un paradigma esencial en muchos lenguajes de programación modernos, y Kotlin no es la excepción. Kotlin ofrece una implementación clara y concisa de los principios de POO, integrando características que facilitan la escritura de código limpio y mantenible. A continuación, exploraremos los conceptos fundamentales de la POO en Kotlin y cómo aplicarlos en tus proyectos.
Clases y objetos en Kotlin
En Kotlin, las clases se definen utilizando la palabra clave class
. Una clase es un molde a partir del cual se crean objetos, que son instancias concretas de esa clase.
Definición de una clase
class Persona(val nombre: String, var edad: Int)
En este ejemplo, Persona
es una clase con dos propiedades: nombre
y edad
. La palabra clave val
indica que nombre
es una propiedad de solo lectura, mientras que var
indica que edad
es mutable.
Creación de objetos
Para crear una instancia de la clase Persona
:
val persona = Persona("Ana", 30)
println("Nombre: ${persona.nombre}, Edad: ${persona.edad}")
Este código creará un objeto persona
con el nombre "Ana" y edad 30.
Constructores en Kotlin
Kotlin proporciona un constructor primario y constructores secundarios para inicializar objetos.
Constructor primario
El constructor primario se define junto al nombre de la clase:
class Coche(val marca: String, val modelo: String)
Constructores secundarios
Si necesitas más de un constructor, puedes definir constructores secundarios utilizando constructor
:
class Coche {
val marca: String
val modelo: String
constructor(marca: String, modelo: String) {
this.marca = marca
this.modelo = modelo
}
constructor(marca: String) {
this.marca = marca
this.modelo = "Modelo desconocido"
}
}
Herencia en Kotlin
La herencia permite crear nuevas clases a partir de clases existentes. En Kotlin, todas las clases son finales por defecto, es decir, no se pueden heredar a menos que se declaren como open
.
Declaración de una clase base
open class Animal(val nombre: String) {
fun comer() {
println("$nombre está comiendo")
}
}
Subclase que hereda de una clase base
class Perro(nombre: String) : Animal(nombre) {
fun ladrar() {
println("$nombre está ladrando")
}
}
Aquí, Perro
es una subclase de Animal
y hereda sus propiedades y métodos.
Modificadores de visibilidad
Kotlin ofrece cuatro modificadores de visibilidad: private
, protected
, internal
y public
(este último es el predeterminado).
private
: Visible solo dentro de la clase.protected
: Comoprivate
, pero también visible en subclases.internal
: Visible dentro del mismo módulo.public
: Visible en todas partes.
Ejemplo
open class Empleado {
private val id: Int = 1
protected val nombre: String = "Juan"
internal val departamento: String = "Ventas"
val puesto: String = "Gerente"
}
Polimorfismo en Kotlin
El polimorfismo permite tratar objetos de diferentes clases de forma unificada basándose en una clase base común.
Sobrescritura de métodos
Para que un método pueda ser sobrescrito en una subclase, debe declararse con open
. La sobrescritura se realiza con override
.
open class Vehiculo {
open fun conducir() {
println("Conduciendo un vehículo")
}
}
class Coche : Vehiculo() {
override fun conducir() {
println("Conduciendo un coche")
}
}
Uso del polimorfismo
fun main() {
val vehiculo: Vehiculo = Coche()
vehiculo.conducir() // Salida: Conduciendo un coche
}
En este ejemplo, aunque vehiculo
se declara como tipo Vehiculo
, en tiempo de ejecución se utiliza la implementación de Coche
.
Encapsulación en Kotlin
La encapsulación consiste en ocultar los detalles internos de una clase y exponer solo lo necesario. Esto se logra mediante el uso de modificadores de visibilidad y propiedades con getters y setters personalizados.
Propiedades con acceso controlado
class CuentaBancaria {
var saldo: Double = 0.0
private set
fun depositar(cantidad: Double) {
if (cantidad > 0) {
saldo += cantidad
}
}
fun retirar(cantidad: Double) {
if (cantidad > 0 && cantidad <= saldo) {
saldo -= cantidad
}
}
}
En este ejemplo, el setter de saldo
es privado; por lo tanto, solo puede modificarse a través de los métodos depositar
y retirar
.
Clases abstractas e interfaces
Kotlin soporta clases abstractas e interfaces para definir contratos que las clases concretas deben implementar.
Clases abstractas
Una clase abstracta no puede instanciarse y puede contener métodos abstractos y concretos.
abstract class Figura {
abstract fun area(): Double
fun describir() {
println("Soy una figura geométrica")
}
}
Interfaces
Las interfaces pueden contener métodos abstractos y métodos con implementación.
interface Dibujable {
fun dibujar()
fun mover(x: Int, y: Int) {
println("Moviendo a coordenadas ($x, $y)")
}
}
Implementación
class Circulo(val radio: Double) : Figura(), Dibujable {
override fun area(): Double {
return Math.PI * radio * radio
}
override fun dibujar() {
println("Dibujando un círculo de radio $radio")
}
}
Data classes
Las data classes
son clases diseñadas para almacenar datos y proporcionan implementaciones automáticas de métodos comunes como toString()
, equals()
y hashCode()
.
Definición de una data class
data class Usuario(val id: Int, val nombre: String)
Uso
val usuario1 = Usuario(1, "María")
val usuario2 = Usuario(2, "Carlos")
println(usuario1) // Salida: Usuario(id=1, nombre=María)
Clases anidadas e internas
Kotlin permite definir clases dentro de otras clases.
Clase anidada (nested class)
Por defecto, una clase definida dentro de otra es estática.
class Contenedor {
class Anidada {
fun mensaje() = "Dentro de la clase anidada"
}
}
val mensaje = Contenedor.Anidada().mensaje()
println(mensaje)
Clase interna (inner class)
Para acceder a los miembros de la clase externa, se utiliza inner
.
class Externa(val valor: Int) {
inner class Interna {
fun doble() = valor * 2
}
}
val externa = Externa(5)
val resultado = externa.Interna().doble()
println(resultado) // Salida: 10
Enumeraciones (enum classes)
Las enum classes
representan un conjunto de constantes.
Definición y uso
enum class Direccion {
NORTE, SUR, ESTE, OESTE
}
val direccion = Direccion.NORTE
println(direccion)
Objetos singleton
En Kotlin, puedes crear objetos singleton utilizando la palabra clave object
.
Definición de un objeto singleton
object GestorConfiguracion {
val configuraciones = mutableMapOf<String, String>()
fun agregarConfiguracion(clave: String, valor: String) {
configuraciones[clave] = valor
}
}
Uso
GestorConfiguracion.agregarConfiguracion("tema", "oscuro")
println(GestorConfiguracion.configuraciones)
Lecciones de este módulo de Kotlin
Lecciones de programación del módulo Programación Orientada a Objetos del curso de Kotlin.
Ejercicios de programación en este módulo de Kotlin
Evalúa tus conocimientos en Programación Orientada a Objetos con ejercicios de programación Programación Orientada a Objetos de tipo Test, Puzzle, Código y Proyecto con VSCode.