Clases
## Objetivos de Aprendizaje
- Comprender declaraciones de clases y constructores
- Trabajar con propiedades
- Crear data classes
- Usar expresiones de objeto y objetos complementarios
- Aprender sobre funcionalidad de copia
## Declaración de Clase
### Clase Básica
```kotlin
class Person {
var name: String = ""
var age: Int = 0
fun introduce() {
println("Hi, I'm $name, age $age")
}
}
fun main() {
val person = Person()
person.name = "Alice"
person.age = 30
person.introduce()
}
```
## Constructores
### Constructor Primario
```kotlin
class Person(val name: String, var age: Int) {
fun introduce() {
println("Hi, I'm $name, age $age")
}
}
fun main() {
val person = Person("Alice", 30)
person.introduce()
}
```
### Propiedades del Constructor
El constructor primario puede declarar propiedades directamente:
```kotlin
class Person(val name: String, var age: Int)
```
Esto es equivalente a:
```kotlin
class Person(name: String, age: Int) {
val name: String = name
var age: Int = age
}
```
### Valores por Defecto en Constructor
```kotlin
class Person(val name: String, var age: Int = 18) {
fun introduce() {
println("Hi, I'm $name, age $age")
}
}
fun main() {
val person1 = Person("Alice")
person1.introduce() // Hi, I'm Alice, age 18
val person2 = Person("Bob", 25)
person2.introduce() // Hi, I'm Bob, age 25
}
```
### Constructores Secundarios
```kotlin
class Person {
val name: String
var age: Int
constructor(name: String) {
this.name = name
this.age = 0
}
constructor(name: String, age: Int) {
this.name = name
this.age = age
}
fun introduce() {
println("Hi, I'm $name, age $age")
}
}
fun main() {
val baby = Person("Charlie")
baby.introduce() // Hi, I'm Charlie, age 0
val adult = Person("Diana", 35)
adult.introduce() // Hi, I'm Diana, age 35
}
```
### Bloques Init
```kotlin
class Person(name: String, var age: Int) {
val name: String
init {
this.name = name.uppercase()
require(age >= 0) { "Age cannot be negative" }
}
fun introduce() {
println("Hi, I'm $name, age $age")
}
}
fun main() {
val person = Person("alice", 30)
person.introduce() // Hi, I'm ALICE, age 30
}
```
## Propiedades
### Propiedades de Solo Lectura (val)
```kotlin
class Person(val name: String, val birthYear: Int) {
val age: Int
get() = 2024 - birthYear
fun introduce() {
println("$name is $age years old")
}
}
fun main() {
val person = Person("Alice", 1990)
person.introduce() // Alice is 34 years old
}
```
### Getters y Setters Personalizados
```kotlin
class Person {
var name: String = ""
set(value) {
field = value.trim()
}
get() = field.ifEmpty { "Unknown" }
var age: Int = 0
set(value) {
if (value >= 0) {
field = value
}
}
}
fun main() {
val person = Person()
println(person.name) // Unknown
person.name = " Alice "
println(person.name) // Alice
person.age = -5 // Ignored
println(person.age) // 0
}
```
### Inicialización Tardía
```kotlin
class Person {
lateinit var name: String
fun initialize() {
name = "Alice"
}
fun introduce() {
if (::name.isInitialized) {
println("Hi, I'm $name")
}
}
}
fun main() {
val person = Person()
person.introduce() // Nothing printed
person.initialize()
person.introduce() // Hi, I'm Alice
}
```
## Data Classes
Las data classes generan automáticamente:
- `equals()` / `hashCode()`
- `toString()`
- Funciones `componentN()`
- `copy()`
```kotlin
data class User(val name: String, val email: String, val age: Int)
fun main() {
val user1 = User("Alice", "alice@example.com", 30)
val user2 = User("Alice", "alice@example.com", 30)
println(user1) // User(name=Alice, email=alice@example.com, age=30)
// Automatic equality check
println(user1 == user2) // true
println(user1.hashCode() == user2.hashCode()) // true
// Destructuring
val (name, email, age) = user1
println("$name, $email, $age")
}
```
### Función Copy
```kotlin
data class User(val name: String, val email: String, val age: Int)
fun main() {
val alice = User("Alice", "alice@example.com", 30)
// Copy with modified fields
val olderAlice = alice.copy(age = 31)
println(alice) // User(name=Alice, email=alice@example.com, age=30)
println(olderAlice) // User(name=Alice, email=alice@example.com, age=31)
// Copy with different email
val newEmailAlice = alice.copy(email = "newalice@example.com")
println(newEmailAlice)
}
```
## Expresiones de Objeto
### Objetos Anónimos
```kotlin
fun main() {
val person = object {
val name: String = "Anonymous"
val age: Int = 25
fun introduce() {
println("Hi, I'm $name")
}
}
person.introduce()
}
```
### Expresiones de Objeto con Interfaces
```kotlin
interface Greeter {
fun greet(): String
}
fun main() {
val greeter = object : Greeter {
override fun greet() = "Hello!"
}
println(greeter.greet())
}
```
## Objetos Complementarios
Un objeto complementario proporciona funcionalidad similar a los métodos estáticos en Java:
```kotlin
class Person(val name: String) {
companion object {
private var count = 0
fun createAnonymous(): Person {
count++
return Person("Person #$count")
}
const val SPECIES = "Human"
}
}
fun main() {
val p1 = Person.createAnonymous()
val p2 = Person.createAnonymous()
println(p1.name) // Person #1
println(p2.name) // Person #2
println(Person.SPECIES) // Human
}
```
### Objeto Complementario como Objeto Nombrado
```kotlin
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
fun main() {
val obj = MyClass.Factory.create()
// or simply
val obj2 = MyClass.create()
}
```
## Clases Selladas
```kotlin
sealed class Result {
data class Success(val data: T) : Result()
data class Error(val message: String) : Result()
object Loading : Result()
}
fun main() {
val result: Result = Result.Success("Hello")
when (result) {
is Result.Success -> println("Success: ${result.data}")
is Result.Error -> println("Error: ${result.message}")
is Result.Loading -> println("Loading...")
}
}
```
## Clases Enum
```kotlin
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF);
fun hex() = "#${Integer.toHexString(rgb)}"
}
fun main() {
val color = Color.BLUE
println(color) // BLUE
println(color.hex()) // #ff0000
// Iterate over enum values
for (c in Color.entries) {
println("${c.name}: ${c.hex()}")
}
}
```
## Resumen
- Las clases se declaran con la palabra clave `class`
- El constructor primario se define en el encabezado de la clase
- Las propiedades usan `val` (solo lectura) o `var` (mutable)
- `data class` auto-genera equals, hashCode, toString, copy
- Las expresiones de objeto crean objetos anónimos
- El objeto complementario proporciona miembros tipo estáticos
- Las clases selladas restringen la herencia para when exhaustivo
- Las clases enum representan un conjunto fijo de valores
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →