Programación orientada a objetos
La programación orientada a objetos (POO) es un paradigma de programación que se enfoca en el uso de “objetos” como unidades básicas de programación. Un objeto es una instancia de una clase, que es una plantilla o molde para crear objetos.
Un objeto tiene dos partes principales: propiedades (también conocidos como variables de instancia) y métodos (también conocidos como funciones de instancia). Los propiedades representan las características de un objeto, mientras que los métodos representan las acciones que un objeto puede realizar.
La POO se basa en tres principios fundamentales: encapsulamiento, herencia y polimorfismo. El encapsulamiento se refiere a la ocultación de los detalles de implementación de un objeto, permitiendo que los objetos interactúen entre sí a través de una interfaz pública. La herencia permite que una clase herede las características y comportamientos de otra clase, mientras que el polimorfismo permite que un objeto tome diferentes formas dependiendo del contexto.
La POO tiene muchas ventajas, como la reutilización de código, la organización, la modularidad del código, la facilidad de mantenimiento y depuración. Sin embargo, también tiene algunos desafíos, como el diseño y la complejidad del código.
En JARU, se pueden crear clases utilizando la palabra clave class seguida del nombre de la clase. Dentro de la clase, se pueden definir propiedades (variables) y métodos (funciones) que son específicos para esa clase. Los objetos se crean a partir de la clase y tienen acceso a los atributos y métodos de esa clase.
Por ejemplo, se puede crear una clase “Auto” con atributos como “marca”, “modelo” y “año”, y métodos como “encender” y “apagar”. Se pueden crear varios objetos de la clase “Auto”, cada uno con valores diferentes para los atributos pero con acceso a los mismos métodos
Declaracion de clases
Como se ha explicado, en el lenguaje de programación JARU, las clases son una herramienta fundamental para la programación orientada a objetos. Una clase es un molde o plantilla para crear objetos que comparten características y comportamientos específicos.
La declaración de una clase en JARU se inicia con la palabra clave class seguida del nombre de la clase. Por ejemplo:
class Persona
// propiedades y metodos van aqui
end
En este caso, acabamos de crear una clase llamada “Persona”. Dentro de esta clase podemos declarar propiedades y métodos. Las propiedades son variables que representan características de un objeto, mientras que los métodos son funciones que representan acciones o comportamientos de un objeto
Declaracion de propiedades
En el lenguaje de programación JARU, las propiedades son valores asociados a una instancia de una clase. Estas propiedades pueden ser creadas en tiempo de ejecución y pueden ser accedidas y modificadas tanto desde dentro de la clase (utilizando la palabra clave this) como desde fuera de la clase con la sintaxis miClase.propiedad.
La palabra clave this en JARU se refiere a la instancia actual de un objeto en una clase. Se utiliza para acceder a las propiedades y métodos de la clase desde dentro de la misma.
La declaración de propiedades en JARU se realiza de manera dinámica, es decir, no es necesario declararlas previamente en la clase. El método init, el cual se vera con mas detalle en el apartado “Constructores”, es una forma común de inicializar las propiedades al momento de crear una nueva instancia de una clase y asegurarse que todos los objetos creados de esa clase tienen esas propiedades.
Por ejemplo, si queremos crear una clase “Persona” con una propiedad “nombre“, podemos hacerlo de la siguiente manera:
class Persona
def init (nombre)
this.nombre = nombre
end
end
var p1 = Persona ("Juan")
var p2 = Persona ("Maria")
print(p1.nombre) // muestra "Juan"
print(p2.nombre) // muestra "Maria"
En este ejemplo, se crea una clase “Persona” con un método init que recibe como parámetro el nombre de la persona y lo asigna a la propiedad “nombre” de la instancia del objeto. Luego, se crean dos objetos “p1” y “p2” de la clase “Persona” y se les asigna un nombre distinto. Al imprimir el valor de la propiedad “nombre” de cada objeto, vemos que es diferente para cada uno.
Además de ser inicializadas en el método init, las propiedades también pueden ser creadas y modificadas desde dentro de otros métodos de la clase o desde fuera de ella, utilizando la notación objeto.propiedad
Para crear una propiedad en un objeto de una clase en JARU desde fuera de la clase, debemos primero instanciar el objeto de la clase. Una vez hecho esto, podemos acceder a las propiedades del objeto y asignarles un valor. Por ejemplo, si tenemos una clase llamada “Persona” y queremos crear la propiedad “alias“, podemos crear un objeto de la clase “Persona” y asignarle un nombre de la siguiente manera:
class Persona
def init()
end
end
var juan = Persona()
juan.alias = "Krilin" // Crea la propiedad "alias" en el objeto "juan"
print(juan.alias)
Las propiedades son asociadas a una instancia de un objeto, no a la clase en sí. Esto quiere decir que cada vez que se crea una nueva instancia de una clase, se crea una copia independiente de sus propiedades asociada a la instancia
Declaracion de metodos
Los métodos son funciones que se definen dentro de una clase y tienen acceso a las propiedades de la misma. La sintaxis para declarar un método en JARU es la palabra clave def seguida del nombre del método, los parámetros entre paréntesis. La declaración de un método debe finalizar con la palabra clave “end”.
A continuación, se presenta un ejemplo de cómo declarar un método “saludar” en una clase “Persona“:
class Persona
def saludar()
print("Hola!")
end
end
En este ejemplo, se ha declarado una clase “Persona” con un método “saludar” que simplemente imprime en la consola el mensaje “Hola!“. El método “saludar” no tiene ningún parámetro ni retorna ningún valor.
Los métodos también pueden tener parámetros y retornar valores. A continuación, se presenta un ejemplo de cómo declarar un método “sumar” en una clase “Calculadora” que recibe dos parámetros y retorna la suma de estos:
class Calculadora
def sumar(a, b)
return a + b
end
end
En este ejemplo, se ha declarado una clase “Calculadora” con un método “sumar” que recibe dos parámetros “a” y “b” y retorna la suma de estos. Es importante mencionar que en JARU, al igual que en otras lenguajes de programación, cuando un método retorna un valor, este puede ser asignado a una variable o utilizado en alguna otra expresión.
Los métodos también pueden acceder a las propiedades de una clase, para esto se utiliza la palabra this seguida del nombre de la propiedad, en el siguiente ejemplo vemos como se accede a una propiedad “nombre” y se utiliza en un método “saludar“
class Persona
def init()
this.nombre = ""
end;
def saludar()
print("Hola! " + this.nombre)
end
end
En este caso se accede a la propiedad “nombre” desde el método “saludar” y se concatena con el mensaje “Hola!”
Constructores
El constructor es un método especial llamado init() que se utiliza para inicializar un objeto de una clase al momento de su creación. La sintaxis de un constructor en JARU es la siguiente:
class NombreDeLaClase
def init()
// código de inicialización
end
end
El constructor se llama automáticamente cuando se crea un nuevo objeto de una clase. El nombre del constructor siempre debe ser init y debe estar dentro de la definición de la clase.
Dentro del constructor, se pueden inicializar las propiedades de la clase utilizando la palabra clave “this”, que hace referencia al objeto actual.
Por ejemplo:
class Persona
def init()
this.nombre = "Sin nombre"
this.edad = 0
end
end
En este ejemplo, se crea una clase “Persona” con un constructor que inicializa las propiedades “nombre” y “edad” con valores predeterminados. Cada vez que se crea un nuevo objeto de la clase “Persona“, el constructor se ejecutará automáticamente y establecerá estos valores en las propiedades del objeto.
También es posible pasar parámetros al constructor para inicializar las propiedades con valores específicos. Por ejemplo:
class Persona
def init(nombre, edad)
this.nombre = nombre
this.edad = edad
end
end
En este ejemplo, se crea una clase “Persona” con un constructor que recibe dos parámetros: “nombre” y “edad“. Cada vez que se crea un nuevo objeto de la clase “Persona”, se deben proporcionar estos dos valores, que se establecerán en las propiedades del objeto.
Sobrecarga de Constructores
En JARU se permite la sobrecarga del método constructor init, que se refiere a la capacidad de tener varias versiones de este método con diferentes argumentos. Esta caracteristica permite crear instancias de una clase de diferentes maneras, dependiendo de los datos disponibles o de las necesidades específicas del programa.
Un ejemplo de sobrecarga del método init en JARU sería una clase “Persona” que tiene como propiedad el nombre y la edad. Se pueden crear varios constructores con diferentes combinaciones de argumentos para inicializar una nueva persona de diferentes formas:
class Persona
def init( nombre, edad)
this.nombre = nombre
this.edad = edad
end;
def init(nombre):
this.nombre = nombre
this.edad = 0
end
end
var p1 = Persona("Juan", 25)
var p2 = Persona("Maria")
En el ejemplo anterior, la primera versión del método init espera dos argumentos: una cadena con el nombre y un numero con la edad de la persona. La segunda versión del método init solo espera un argumento: una cadena con el nombre de la persona.
Al crear una nueva instancia de la clase Persona con dos argumentos (“Juan”, 25), se ejecutará la primera versión del método init y se inicializarán las propiedades nombre y edad de la persona. Por otro lado, al crear una nueva instancia con solo un argumento (“Maria”), se ejecutará la segunda versión del método init y se inicializará solo la propiedad nombre con el valor especificado, mientras que la propiedad edad se inicializará con 0.
La sobrecarga del método init es una técnica muy útil para crear objetos de diferentes formas y adaptarse a las necesidades específicas del programa, permitiendo una mayor flexibilidad y mejorando la reutilizabilidad del código.
Herencia de clases
La herencia en programación orientada a objetos es un mecanismo que permite a una clase (llamada clase hija o subclase) heredar las propiedades y métodos de otra clase (llamada clase padre o superclase). De esta manera, la clase hija puede reutilizar código ya existente y ampliar o modificar su comportamiento según sea necesario.
Por ejemplo, si tenemos una clase “Animal” con propiedades como nombre y número de patas, y una clase “Perro” que hereda de “Animal”, entonces “Perro” tendría acceso a las propiedades “nombre” y “número de patas” de “Animal” y podría añadir propiedades específicas como “raza”.
En JARU, el concepto de herencia se implementa mediante el uso de los dos puntos :. Cuando se declara una clase, se puede especificar otra clase de la cual se heredarán sus propiedades y métodos. Esto se hace al colocar el nombre de la clase padre después de los dos puntos al momento de declarar la clase hija.
Por ejemplo:
class Padre
def init()
propiedad1 = "Valor"
end
def metodo1()
print("Hola, soy el método 1 del padre")
end
end
class Hijo: Padre
def metodo2()
print("Hola, soy el método 2 del hijo")
end
end
En este ejemplo, la clase Hijo hereda de la clase Padre, por lo que tiene acceso a la propiedad “propiedad1” y al método “metodo1”, y puede también tener sus propias propiedades y métodos.
Además, con la herencia se puede acceder a las propiedades y métodos del padre mediante la notación de punto (.) y el nombre de la propiedad o método, por ejemplo Hijo.propiedad1 o Hijo.metodo1(). También se puede sobre escribir un método o propiedad del padre en el hijo si se declara con el mismo nombre en el hijo.
Veamos otro ejemplo, si se tiene una clase llamada “Animales” y se quiere crear una clase llamada “Perros” que herede de “Animales“, se puede declarar de la siguiente manera:
class Animales
def init():
this.especie = "No especificado"
end
def caminar():
print("Caminando")
end
end
class Dogs : Animales
def init():
this.raza = "No especificado"
end
def ladrar():
print("Ladrando")
end
end
En este ejemplo, la clase “Perros” hereda de la clase “Animal” y tiene acceso a sus propiedades y métodos.
Encapsulamiento
El encapsulamiento es un principio fundamental de la programación orientada a objetos que se refiere a la ocultación de detalles de implementación de una clase o objeto. Esto se logra mediante el uso del modificador de acceso private.
En JARU, el modificador de acceso private se utiliza para declarar propiedades y métodos que solo pueden ser accedidos desde dentro de la clase en la que se declararon. Esto significa que estas propiedades y métodos no pueden ser accedidos desde fuera de la clase, incluso desde objetos instanciados de esa clase.
Por ejemplo, consideremos la siguiente clase “Persona” con una propiedad privada “edad“:
class Persona
private edad
def init(edad)
this.edad = edad
end
end
var p = Persona(25)
print(p.edad) // Error, la propiedad edad es privada
En este ejemplo, la propiedad “edad” es declarada como privada y solo puede ser accedida desde dentro de la clase “Persona“. Si intentamos acceder a esta propiedad desde un objeto instanciado de la clase “Persona”, obtendremos un error.
El encapsulamiento con la cláusula private es útil para proteger las propiedades y métodos de una clase de posibles errores y modificaciones no deseadas desde fuera de la clase. También permite cambiar la implementación interna de una clase sin afectar a las clases o objetos que la utilizan.
Es importante mencionar que en JARU no existe la cláusula protected, pero si se puede acceder a las propiedades y metodos privado desde una clase hija mediante la herencia.
Polimorfismo
El polimorfismo es uno de los pilares de la programación orientada a objetos que permite que un objeto de una clase pueda ser tratado como si fuera de otra clase relacionada. Esto significa que una misma acción puede tener distintos comportamientos en diferentes objetos, dependiendo de su clase.
Por ejemplo, imagine que tiene una clase llamada “Animal” y dos subclases “Gato” y “Perro”. La clase “Animal” tiene un método llamado “hacerRuido” que se sobreescribe en las subclases “Gato” y “Perro” para emitir un sonido diferente. Cuando se crean objetos de cada subclase y se les llama a hacerRuido, cada objeto emite un sonido distinto, pero aún así pueden ser tratados como si fueran objetos de la clase “Animal”.
Otro ejemplo puede ser una clase “FiguraGeométrica” con subclases “Círculo” y “Rectángulo”. La clase “FiguraGeométrica” tiene un método llamado “calcularArea” que se sobreescribe en las subclases “Círculo” y “Rectángulo” para calcular el área de la figura de manera diferente. Cuando se crean objetos de cada subclase y se les llama a calcularArea, cada objeto devuelve un área diferente, pero aún así pueden ser tratados como si fueran objetos de la clase “FiguraGeométrica”.
En resumen, el polimorfismo permite que se utilice una misma acción o método con distintos objetos, y dependiendo de su clase, se realice una acción diferente.