← Scala EspañolChapter 07 of 13

Clases

## Objetivos de Aprendizaje - Dominar definiciones de clases - Trabajar con constructores - Comprender objetos companion - Aprender case classes - Dominar conceptos basicos de OOP en Scala ## Basicos de Clases ### Definiendo una Clase ```scala class Person { var name: String = "" var age: Int = 0 def greet(): String = s"Hello, I'm $name" } val person = new Person() person.name = "Alice" person.age = 30 println(person.greet()) // Hello, I'm Alice ``` ### Constructor Primario Los parametros de clase se convierten en el constructor primario: ```scala class Person(val name: String, var age: Int) { def greet(): String = s"Hello, I'm $name" } val alice = new Person("Alice", 30) println(alice.name) // Alice println(alice.age) // 30 alice.age = 31 // OK - var // alice.name = "Bob" // Error - val ``` ### Constructor con Valores por Defecto ```scala class Person(val name: String = "Unknown", var age: Int = 0) { def greet(): String = s"Hello, I'm $name" } val unknown = new Person() // name="Unknown", age=0 val bob = new Person("Bob") // name="Bob", age=0 val alice = new Person("Alice", 30) // name="Alice", age=30 ``` ## Constructores Auxiliares ```scala class Person(val name: String, var age: Int) { def this(name: String) = this(name, 0) // Constructor auxiliar def this() = this("Unknown", 0) // Otro auxiliar override def toString = s"Person($name, $age)" } val p1 = new Person("Alice", 30) val p2 = new Person("Bob") val p3 = new Person() ``` ## Modificadores de Visibilidad ### Miembros Privados ```scala class BankAccount(private var balance: Double) { def deposit(amount: Double): Unit = { if (amount > 0) balance += amount } def withdraw(amount: Double): Boolean = { if (amount > 0 && amount <= balance) { balance -= amount true } else { false } } def getBalance: Double = balance // Getter } val account = new BankAccount(100) account.deposit(50) account.withdraw(30) println(account.getBalance) // 120 // account.balance // Error: balance es privado ``` ### Generacion de getter y setter ```scala class Person { var name: String = _ // Genera getter y setter val id: Int = 0 // Solo genera getter private var balance: Double = 0 // No se genera getter/setter private[this] var secret: String = "" // Privado del objeto } ``` ## Objetos Companion Un objeto companion tiene el mismo nombre que la clase: ```scala class Person(val name: String, val age: Int) { override def toString = s"Person($name, $age)" } object Person { def apply(name: String, age: Int): Person = new Person(name, age) def apply(name: String): Person = new Person(name, 0) def createStudent(name: String, age: Int): Person = { if (age < 0) throw new IllegalArgumentException("Invalid age") new Person(name, age) } } // Usando companion val p1 = Person("Alice", 30) // metodo apply val p2 = Person("Bob") // apply con edad por defecto val p3 = Person.createStudent("Charlie", 25) ``` ## Case Classes Las case classes generan automaticamente: - parametros val (campos inmutables) - metodos apply, unapply, copy - toString, equals, hashCode ```scala case class Person(name: String, age: Int) { def greet(): String = s"Hello, I'm $name" } val alice = Person("Alice", 30) // No se necesita 'new' - apply se genera val bob = Person("Bob", 25) // Inmutable - no var permitido por defecto // alice.age = 31 // Error! // Copia con modificaciones val aliceOlder = alice.copy(age = 31) // Emparejamiento de patrones alice match { case Person(n, a) => s"$n is $a years old" } // Igualdad val alice2 = Person("Alice", 30) alice == alice2 // true (equals generado) // Uso en hash map val people = Set(alice, alice2) // Set contiene solo un Person("Alice", 30) ``` ## Objects Los objects son instancias singleton: ```scala object Config { val defaultTimeout = 30 val maxRetries = 3 def getSetting(key: String): String = { // Cargar desde config key match { case "timeout" => defaultTimeout.toString case "retries" => maxRetries.toString case _ => "unknown" } } } println(Config.defaultTimeout) // 30 println(Config.getSetting("timeout")) // 30 ``` ## Clase vs Object vs Case Class | Caracteristica | Clase | Object | Case Class | |----------------|-------|--------|------------| | Instanciacion | new | Instancia unica | new (o apply) | | Parametros | var/val | N/A | val por defecto | | Metodos | Si | Si | Si | | extends | Si | Si | Si | | equals/hashCode | Referencia | N/A | Generado | | apply | No generado | Si | Generado | | unapply | No generado | Si | Generado | | copy | No generado | N/A | Generado | ## Clases Abstractas ```scala abstract class Shape { def area(): Double def perimeter(): Double } class Circle(val radius: Double) extends Shape { def area(): Double = Math.PI * radius * radius def perimeter(): Double = 2 * Math.PI * radius } class Rectangle(val width: Double, val height: Double) extends Shape { def area(): Double = width * height def perimeter(): Double = 2 * (width + height) } ``` ## Clases Anidadas ```scala class Outer { class Inner { def hello() = "Hello from Inner" } def createInner(): Inner = new Inner() } val outer = new Outer() val inner = outer.createInner() println(inner.hello()) ``` ## Estructuras Tipo Enum ```scala object Color extends Enumeration { val Red = Value val Green = Value val Blue = Value val Yellow = Value("YELLOW") } import Color._ Red match { case Red => "Red" case Green => "Green" case Blue => "Blue" case _ => "Other" } ``` ## Resumen - Las clases definen blueprints; los objects son instancias singleton - Los parametros del constructor primario pueden ser val o var - Los miembros privados ocultan detalles de implementacion - Los objetos companion proporcionan metodos de fabrica y utilidades estilo estatico - Las case classes generan automaticamente boilerplate para datos inmutables - La copia de case class crea copias modificadas - Las clases abstractas definen contratos para subclases - Usa objects para funciones de utilidad y estado singleton

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →