En Scala, cuando pensamos en objetos, es importante distinguir entre dos conceptos fundamentales: las clases y los objetos Singleton. Las clases en Scala funcionan de manera similar a como lo hacen en otros lenguajes orientados a objetos, como Java. Son estructuras que contienen variables, llamadas campos, y métodos que manipulan el estado de esas instancias. Sin embargo, a diferencia de Java, Scala no permite que las clases tengan variables o métodos estáticos. Esto significa que no podemos definir operaciones que se puedan ejecutar sin crear una instancia de la clase.
Para cubrir esta necesidad, Scala introduce los objetos Singleton, que son una forma especial de objeto que no se puede instanciar múltiples veces. En realidad, solo existe una única instancia de cada objeto Singleton, y se definen usando la palabra clave object. Estos objetos actúan como contenedores de métodos y valores que podemos llamar directamente, sin necesidad de crear un objeto nuevo. Es decir, funcionan como si fueran métodos estáticos, pero con una distinción clara: separan radicalmente el concepto de clase (que se puede instanciar) del de objeto Singleton (que no).
Para declarar un objeto Singleton en Scala, simplemente escribimos object seguido del nombre que queramos darle. Dentro de las llaves podemos definir funciones y valores que estarán disponibles para ser usados directamente a través del nombre del objeto. Por ejemplo, podríamos crear un objeto llamado MiObjeto con funciones para sumar y restar dos números enteros:
object MiObjeto {
def sumar(a: Int, b: Int): Int = a + b
def restar(a: Int, b: Int): Int = a - b
}
Una vez definido, podemos llamar a estas funciones sin necesidad de crear una instancia, simplemente usando MiObjeto.sumar(1, 2), lo que nos devolverá 3. Esta forma de organizar el código es muy útil para agrupar funciones relacionadas que no necesitan mantener estado entre llamadas.
Además, los objetos Singleton son especialmente importantes para definir el punto de entrada de un programa Scala. Podemos crear un objeto, por ejemplo llamado Aplicacion, que contenga una función main con la firma típica que recibe un array de cadenas como argumentos y no devuelve nada. Dentro de esta función podemos escribir código que se ejecute al iniciar el programa, como imprimir un mensaje en pantalla:
object Aplicacion {
def main(args: Array[String]): Unit = {
println("Hola mundo")
}
}
Este enfoque nos permite ejecutar programas Scala completos sin depender únicamente del intérprete interactivo. Cuando compilamos el código con scalac, el compilador busca un objeto que tenga un método main para saber dónde comenzar la ejecución. Así, los objetos Singleton se convierten en una pieza clave para estructurar programas y facilitar su ejecución.
Aunque más adelante podemos explorar cómo los objetos pueden extender otros objetos o incluir traits para añadir funcionalidades, por ahora es fundamental entender que los objetos Singleton nos permiten definir métodos accesibles sin instanciar y que son la base para crear programas ejecutables en Scala. Esta separación clara entre clases y objetos Singleton es una característica distintiva del lenguaje que combina la orientación a objetos con un enfoque funcional.