PROGRAMACION ORIENTADA A OBJETOS
PROGRAMACION ORIENTADA A OBJETOS
Encapsulación
La Encapsulación es uno de los cuatro pilares fundamentales de la POO, y su propósito principal es ocultar
los detalles internos de una clase y exponer solo lo necesario. Esto hace que el código sea más seguro,
modular y fácil de mantener.
1. ¿Qué es la Encapsulación?
La encapsulación es como poner los datos y funciones de una clase en una "caja" y controlar qué partes de
esa caja se pueden ver o modificar desde afuera. Así, la clase tiene control total sobre su información y
funcionamiento interno.
Por ejemplo, imagina una clase llamada CuentaBancaria. No querríamos que cualquiera pueda cambiar el
saldo de la cuenta desde fuera, ya que esto podría causar problemas. Para evitarlo, usamos encapsulación
para controlar cómo se accede y modifica el saldo.
2. Cómo Funciona la Encapsulación en C#
En C#, controlamos el acceso a los datos y métodos de una clase usando modificadores de acceso. Los más
comunes son:
public: Permite acceso desde cualquier parte del código.
private: Restringe el acceso solo dentro de la misma clase.
protected: Permite el acceso dentro de la clase y sus clases derivadas (usado en herencia).
internal: Permite el acceso dentro del mismo ensamblado o proyecto.
Ejemplo de Encapsulación usando private y public
En el siguiente ejemplo, encapsularemos los datos de una clase CuentaBancaria para evitar que el saldo se
modifique desde afuera.
En este ejemplo:
saldo está declarado como private, por lo que solo puede modificarse desde dentro de CuentaBancaria.
ObtenerSaldo, Depositar, y Retirar son public. Estos métodos son accesibles desde fuera de la clase y
permiten controlar cómo se ve o modifica el saldo.
¿Por Qué Usar Encapsulación?
Seguridad: Al ocultar los detalles internos, evitamos que otras partes del programa cambien datos de manera
no deseada.
Modularidad: Puedes hacer cambios en la implementación interna de una clase sin afectar a quienes la usan.
Fácil Mantenimiento: Al usar métodos específicos para interactuar con los datos, puedes controlar los cambios
y actualizaciones de manera más sencilla.
3. Propiedades en C# para Encapsulación
En lugar de usar métodos Obtener y Establecer (o "Get" y "Set") para cada campo privado, C# ofrece una
forma más limpia de acceder y modificar datos encapsulados: propiedades.
Una propiedad permite leer, escribir o calcular el valor de un campo privado a través de get y set, que
funcionan como "puertas" de acceso controlado.
Ejemplo de Encapsulación Usando Propiedades
Aquí:
La propiedad Saldo permite leer el saldo desde afuera usando get, pero el set es privado, lo que significa que
solo la clase puede cambiar el saldo.
Propiedades Automáticas: En C#, se puede simplificar aún más declarando propiedades automáticas para
crear un campo y una propiedad a la vez.
Ejemplo con Propiedad Automática
4. Propiedades de Solo Lectura (Read-Only Properties)
Hay veces que solo queremos que los datos se vean desde fuera, pero no se modifiquen. Para eso usamos
propiedades de solo lectura.
Ejemplo de Propiedad de Solo Lectura
En este ejemplo:
Titulo y Autor solo se pueden establecer en el constructor y no pueden modificarse después.
5. Encapsulación y Métodos Accesores (Getters y Setters)
Antes de las propiedades, los métodos Get y Set eran la manera principal de controlar el acceso a los datos
de una clase.
Ejemplo con Getters y Setters
Ventaja de Propiedades sobre Getters y Setters: Las propiedades hacen que el código sea más limpio y fácil
de leer.
6. Encapsulación y Validación de Datos
Uno de los beneficios clave de la encapsulación es que permite validar los datos antes de cambiarlos. Esto
asegura que los datos internos siempre sean válidos.
Ejemplo de Encapsulación con Validación
En este ejemplo:
Calificacion solo acepta valores entre 0 y 100. Si intentamos asignarle un valor fuera de ese rango, se
mostrará un mensaje de error.
7. Encapsulación y Herencia
En algunos casos, podemos querer que una clase hija acceda a datos privados de la clase padre. En este
caso, usamos el modificador protected para encapsular los datos de una forma que permita el acceso en
clases derivadas.
Ejemplo de protected
En este ejemplo:
nombre es protected, así que la clase Perro, que hereda de Animal, puede acceder y usar este campo.
8. Resumen Final de Encapsulación
La encapsulación organiza y protege los datos de una clase.
Los modificadores de acceso (public, private, protected, internal) determinan quién puede ver o cambiar los
datos.
Las propiedades (con get y set) permiten controlar el acceso y la modificación de los campos de una clase.
La encapsulación permite hacer validaciones antes de cambiar los datos, aumentando la seguridad y
confiabilidad del código.
GET Y
¿Qué son get y set?
SET
get: Este es un "accesor" que recupera el valor de una propiedad. Básicamente, es el método que usamos
cuando queremos leer o ver el valor de un campo privado.
set: Este es un "mutador" que establece o modifica el valor de una propiedad. Se usa cuando queremos
asignar o cambiar el valor de un campo privado.
Cuando declaras una propiedad en C#, puedes usar get y set para definir cómo el código accede o modifica
un campo privado dentro de la clase. Esto permite hacer la encapsulación más intuitiva y segura.
2. ¿Cómo funcionan get y set en una propiedad?
Una propiedad en C# es como una "puerta de acceso controlada" a un campo privado de la clase. Con get y
set, controlas lo que ocurre cuando alguien quiere leer (usar get) o cambiar (usar set) el valor de esa
propiedad.
Ejemplo básico con get y set
En este ejemplo:
nombre es un campo privado y no es accesible directamente desde fuera de la clase.
La propiedad Nombre tiene un get para leer el valor de nombre y un set para asignarle un nuevo valor.
Cuando usamos esta propiedad, se ve así:
Aquí:
[Link] = "Adriana"; llama al set, que asigna "Adriana" al campo nombre.
[Link]([Link]); llama al get, que devuelve el valor "Adriana" para mostrarlo.
3. Controlando el acceso con get y set
Al usar get y set, puedes controlar quién puede ver y modificar los datos en cada propiedad.
Propiedad de solo lectura: Si solo incluyes get, los datos pueden leerse pero no modificarse desde
fuera de la clase.
Propiedad de solo escritura: Si solo incluyes set, los datos pueden modificarse pero no leerse desde
fuera de la clase (poco común, pero útil en ciertos casos).
Ejemplo de una Propiedad de Solo Lectura
Aquí, Titulo solo tiene get, por lo que puedes ver el título, pero no cambiarlo después de que el objeto Libro ha
sido creado.
4. Propiedades Automáticas
C# ofrece una forma más corta de declarar get y set cuando no necesitas lógica adicional: propiedades
automáticas. Esto ahorra el trabajo de crear un campo privado separado, ya que el compilador se encarga de
hacerlo por ti.
Ejemplo con Propiedades Automáticas
Aquí, Nombre es una propiedad automática. Esto es equivalente a declarar un campo privado y agregar un
get y set básicos.
Propiedad Automática de Solo Lectura
Si quieres que una propiedad automática sea de solo lectura, puedes definirla solo con get, o solo permitir que
set sea accesible dentro del constructor:
5. Validación con set
Puedes agregar lógica en set para validar el valor antes de asignarlo al campo. Esto asegura que el valor de
la propiedad sea válido y evita errores o datos incorrectos.
Ejemplo con Validación en set
En este ejemplo:
La propiedad Saldo solo aceptará valores positivos. Si intentas asignar un valor negativo, el set muestra un
mensaje y no actualiza el saldo.
6. Usar private en set para Encapsulación Adicional
A veces, solo quieres que el get sea accesible públicamente, pero no el set. Esto es útil cuando quieres que
solo la propia clase pueda modificar el valor, como en el caso de una cuenta bancaria o una identidad de
usuario.
Ejemplo de private set
En este ejemplo:
Nombre tiene un private set, así que solo puede modificarse desde dentro de la clase Usuario, no desde fuera.
CambiarNombre es un método público que permite cambiar el nombre, pero con una validación.
7. Resumen de get y set
get y set permiten encapsular datos de manera segura.
Con get controlas la lectura del valor de una propiedad; con set, controlas la modificación.
Puedes usar propiedades de solo lectura con solo get o propiedades de solo escritura con solo set.
Propiedades automáticas simplifican el uso de get y set cuando no necesitas lógica adicional.
Validación en set asegura que solo se asignen valores válidos a la propiedad.
private set limita el cambio de una propiedad solo a la propia clase, lo cual es útil para mayor control.
Co
¿Qué es un Constructor?
nst
Un constructor es un método especial que se llama automáticamente cuando se crea un nuevo objeto de una
clase. Su propósito principal es inicializar los datos o configurar el objeto con valores iniciales. Piensa en el
constructor como una especie de "manual de bienvenida" para el objeto: lo configura cuando es creado,
asegurando que tenga todos los valores necesarios desde el inicio.
ruc
Características del Constructor en C#:
Nombre: El constructor siempre tiene el mismo nombre que la clase. Por ejemplo, si tienes una clase
llamada Persona, el constructor también se llamará Persona.
No tiene tipo de retorno: A diferencia de otros métodos, el constructor no devuelve ningún valor, ni
siquiera void.
Se ejecuta automáticamente: Cada vez que creas una instancia de la clase, C# llama automáticamente
tor
al constructor sin necesidad de llamarlo explícitamente.
Ejemplo Básico de Constructor
Aquí tienes una clase con un constructor simple:
En este ejemplo:
La clase Persona tiene un constructor que recibe dos parámetros: nombre y edad.
Este constructor se usa para inicializar los campos Nombre y Edad de cada objeto Persona que creamos.
Para usar el constructor:
Al crear new Persona("Adriana", 49);, estamos llamando al constructor, que asigna "Adriana" a Nombre y 49 a
Edad.
Tipos de Constructores en C#
1. Constructor Predeterminado (Sin Parámetros)
Si no defines un constructor en una clase, C# proporciona uno por defecto (un constructor sin parámetros).
Este constructor predeterminado inicializa los campos con valores estándar:
Los números se inicializan en 0.
Los bool en false.
Las referencias de objetos en null.
Ejemplo
En este caso, Nombre será null y Edad será 0.
2. Constructor con Parámetros
Puedes definir un constructor con parámetros para inicializar los campos con valores específicos, como en el
ejemplo inicial. Este tipo de constructor facilita la creación de objetos completamente configurados desde el
principio.
Ejemplo:
Al crear el objeto con new Persona("Adriana", 49);, le damos valores iniciales a Nombre y Edad.
3. Constructor Sobrecargado (Varios Constructores)
Puedes definir varios constructores en una clase con diferentes parámetros. Esto se llama sobrecarga de
constructores y permite varias formas de crear objetos.
Ejemplo:
Ahora puedes crear objetos Persona de diferentes formas:
4. Constructor Estático
Un constructor estático se utiliza para inicializar datos estáticos de una clase. Solo se ejecuta una vez, la
primera vez que se accede a la clase, y no toma parámetros.
Este constructor se llama automáticamente la primera vez que se usa Ejemplo.
Uso del Constructor en Encapsulación
A menudo, los constructores se combinan con propiedades (get y set) para asegurar que los valores iniciales
de los campos sean válidos. Puedes usar validaciones en el constructor para evitar que se asignen valores no
deseados.
Ejemplo:
Aquí:
El constructor verifica que saldoInicial no sea negativo antes de asignarlo al campo Saldo.
Constructor con Inicialización de Objetos en Juegos (Ejemplo en Unity)
Imaginemos que quieres crear un objeto Personaje en Unity, con un constructor que defina valores básicos,
como el nombre y la vida:
Para crear el personaje en Unity:
Aquí, el constructor asigna un nombre y una vida inicial, con una validación para asegurar que Vida nunca sea
negativa.
Resumen de los Puntos Clave del Constructor en C#
Constructor: Método especial para inicializar un objeto.
Nombre igual a la clase y sin tipo de retorno.
Constructor Predeterminado: Automático si no defines uno.
Constructor con Parámetros: Inicializa con valores específicos.
Sobrecarga de Constructores: Varios constructores con diferentes parámetros.
Constructor Estático: Inicializa miembros estáticos, se ejecuta solo una vez.
Validación en Constructores: Asegura que el objeto siempre tenga valores válidos.
Her
enc
¿Qué es la Herencia?
La herencia es una característica de la POO que permite crear nuevas clases a partir de clases ya existentes,
"heredando" sus atributos y métodos. En pocas palabras, puedes crear una nueva clase (hija) basada en una
clase existente (padre) y extender o modificar su comportamiento.
Piensa en la herencia como una relación entre una "familia" de clases, donde una clase hija hereda
ia
propiedades y métodos de la clase padre, y también puede tener sus propias características únicas.
¿Por qué es útil la Herencia?
Reutilización de código: Al heredar métodos y propiedades, no necesitas escribir el mismo código en
varias clases.
Organización y jerarquía: Ayuda a organizar el código en una estructura jerárquica, facilitando su
mantenimiento.
Extensibilidad: Puedes extender una clase existente con nuevas funcionalidades sin modificar la clase
original.
Ejemplo Básico de Herencia en C#
Para entender mejor la herencia, vamos a crear un ejemplo simple con animales.
1. Clase Padre Animal
La clase Animal tiene dos propiedades (Nombre y Edad) y dos métodos (Comer y Dormir).
2. Clase Hija Perro
Aquí, Perro es una clase que hereda de Animal usando los dos puntos :. Como resultado:
Perro tiene acceso a las propiedades Nombre y Edad, y a los métodos Comer y Dormir de Animal.
Además, Perro añade una propiedad propia llamada Raza y un método llamado Ladrar.
3. Usando la Herencia
En este ejemplo, miPerro tiene todas las funcionalidades de Animal y también las funcionalidades adicionales
específicas de Perro.
Tipos de Herencia
En C#, la herencia es simple: cada clase hija puede tener solo una clase padre directa. Sin embargo, se
pueden usar jerarquías donde una clase puede heredar de otra, formando una cadena.
Ejemplo de Jerarquía
Aquí, Perro hereda de Mamifero, que a su vez hereda de Animal. Perro tiene acceso a todos los miembros de
Mamifero y Animal.
Palabra clave base
La palabra clave base permite que una clase hija acceda a los miembros de su clase padre, ideal para
modificar o ampliar el comportamiento de un método heredado.
Ejemplo con base
En este ejemplo:
Usamos base(nombre) en el constructor de Perro para llamar al constructor de Animal.
[Link]() llama al método HacerSonido de la clase padre.
Palabra clave virtual y override
Para que un método pueda ser modificado en una clase hija, se declara como virtual en la clase padre y
override en la clase hija.
Ejemplo
virtual: Indica que el método HacerSonido de Animal puede ser sobrescrito.
override: Gato redefine HacerSonido con su propia implementación.
Beneficios de Virtual y Override
Polimorfismo: Permite que la clase hija defina su propio comportamiento para un método heredado, lo
que es fundamental en la POO.
Flexibilidad: Las clases hijas pueden adaptar métodos heredados según sus necesidades específicas.
Resumen de Herencia en C#
La herencia permite que una clase hija use y amplíe los métodos y propiedades de una clase padre.
: (dos puntos) se usa para declarar herencia en C#.
La palabra clave base permite acceder a los miembros de la clase padre desde la clase hija.
virtual y override permiten a las clases hijas redefinir métodos para implementar su propio
comportamiento.
Pol
¿Qué es el Polimorfismo?
im
El polimorfismo es un concepto fundamental de la POO que permite que una misma operación o método se
comporte de manera diferente dependiendo del objeto con el que se está trabajando. Es decir, puedes tener el
mismo método en diferentes clases, pero con comportamientos distintos según el tipo de objeto que lo
orf
invoque.
En términos sencillos:
Imagina que tienes varias clases (por ejemplo, Perro, Gato, Pájaro) y cada una tiene un método llamado
HacerSonido. Gracias al polimorfismo, cada uno de estos animales puede hacer un sonido diferente cuando
se llama al mismo método HacerSonido, aunque todos tengan el mismo nombre.
is
¿Por qué es útil el Polimorfismo?
Flexibilidad: Permite que el mismo código funcione de manera diferente según el tipo de objeto.
Extensibilidad: Puedes agregar nuevos tipos de objetos sin modificar el código que ya usa el
polimorfismo.
Simplicidad: Hace que el código sea más sencillo y limpio, ya que puedes usar el mismo método para
diferentes tipos de objetos.
Tipos de Polimorfismo en C#
mo
En C#, existen dos tipos principales de polimorfismo:
Polimorfismo en tiempo de compilación (Overloading): Se refiere a la capacidad de definir múltiples
métodos con el mismo nombre, pero con diferentes parámetros.
Polimorfismo en tiempo de ejecución (Overriding): Permite que un método en una clase hija tenga un
comportamiento diferente que el método correspondiente en la clase padre, usando las palabras clave
virtual y override.
1. Polimorfismo en tiempo de compilación (Overloading)
El overloading ocurre cuando creas varios métodos con el mismo nombre pero con diferentes firmas (es decir,
diferente número o tipo de parámetros). El compilador decide cuál método usar en función de los argumentos
pasados al método.
Ejemplo de Overloading
En este caso, la clase Calculadora tiene tres métodos llamados Sumar, pero con diferentes parámetros. El
compilador selecciona cuál de ellos utilizar en función de los argumentos que le pases.
2. Polimorfismo en tiempo de ejecución (Overriding)
El overriding permite que una clase hija proporcione una implementación específica de un método que ya está
definido en la clase base. Esto se logra usando las palabras clave virtual (en la clase padre) y override (en la
clase hija).
Ejemplo de Overriding
Aquí, HacerSonido es un método virtual en la clase base Animal, lo que significa que las clases hijas pueden
sobrescribirlo. En las clases hijas Perro y Gato, el método es sobrescrito con un comportamiento diferente.
Uso del Polimorfismo en tiempo de ejecución
En este caso, a pesar de que ambas variables animal1 y animal2 son de tipo Animal, cuando llamamos al
método HacerSonido, se ejecuta el método adecuado para cada tipo de objeto (Perro o Gato), gracias al
polimorfismo.
Polimorfismo con Interfaces
En C#, también puedes usar interfaces para lograr polimorfismo. Una interfaz define un contrato que las
clases deben seguir, y puedes tener diferentes clases implementando la misma interfaz, cada una con su
propio comportamiento.
Ejemplo con Interfaces
Uso del Polimorfismo con Interfaces
Aquí, ambas clases implementan la interfaz IHacerSonido, y podemos tratarlas como IHacerSonido, pero
ejecutar el comportamiento adecuado en tiempo de ejecución.
Beneficios del Polimorfismo
Reducción de código duplicado: Permite que diferentes objetos compartan la misma interfaz pero
tengan comportamientos distintos.
Mantenimiento más sencillo: Al tener un único punto de contacto (un método común), el código es más
fácil de mantener y modificar.
Flexibilidad: Puedes agregar nuevos tipos de objetos sin cambiar el código que los utiliza.
Resumen de Polimorfismo en C#
Polimorfismo permite que el mismo método tenga diferentes comportamientos según el tipo de objeto
que lo invoque.
Overloading es el polimorfismo en tiempo de compilación, donde el mismo método tiene diferentes
versiones con diferentes parámetros.
Overriding es el polimorfismo en tiempo de ejecución, donde una clase hija redefine el comportamiento
de un método heredado de la clase base.
Interfaces también pueden ser usadas para implementar polimorfismo, permitiendo que diferentes
clases implementen el mismo contrato con diferentes comportamientos.
Este pilar es crucial cuando trabajas con jerarquías de clases más complejas, ya que te permite tratar objetos
de diferentes tipos de manera uniforme mientras cada uno tiene su propia implementación de los métodos.
Ab
str
¿Qué es la Abstracción?
La Abstracción es el proceso de ocultar los detalles complejos de un sistema y mostrar solo las partes
esenciales de un objeto. En otras palabras, permite trabajar con un nivel más alto de lógica, enfocándose en
los aspectos más importantes mientras se ocultan los detalles internos que no son necesarios.
En términos sencillos:
acc
Imagina que estás conduciendo un coche. No necesitas saber cómo funciona el motor o las ruedas por dentro,
solo necesitas saber cómo encenderlo, acelerarlo, frenar y girar. El coche te ofrece una interfaz sencilla para
que lo conduzcas, sin necesidad de conocer todos los detalles internos.
¿Por qué es importante la Abstracción?
Simplificación del diseño: Te permite gestionar sistemas más complejos mediante la creación de interfaces o
ión
clases abstractas que oculten los detalles internos.
Reducción de complejidad: Ayuda a centrarte solo en lo importante, eliminando los detalles innecesarios.
Mayor mantenimiento: Los cambios en los detalles internos no afectan el comportamiento general del sistema.
Formas de Abstracción en C#
En C#, existen principalmente dos formas de implementar la abstracción:
Clases Abstractas: Una clase que no puede ser instanciada directamente, pero puede ser heredada
por otras clases.
Interfaces: Un contrato que las clases deben cumplir, especificando qué métodos deben tener, pero sin
proporcionar una implementación.
1. Clases Abstractas
Una clase abstracta es una clase que no se puede instanciar directamente. Se usa como base para otras
clases. Puedes definir métodos abstractos en una clase abstracta, los cuales no tienen implementación, y las
clases derivadas deben implementar estos métodos.
Ejemplo de Clase Abstracta
En este ejemplo:
Animal es una clase abstracta.
Tiene un método HacerSonido que es abstracto (sin implementación).
La clase Perro debe sobrescribir el método HacerSonido para proporcionar su propia implementación.
Uso de la clase abstracta
2. Interfaces
Una interfaz en C# es similar a una clase abstracta, pero se usa para definir un contrato sin ninguna
implementación. Las clases que implementan una interfaz deben proporcionar una implementación para todos
los métodos definidos en la interfaz.
Ejemplo de Interfaz
Aquí:
IHacerSonido es una interfaz que define el método HacerSonido.
Las clases Perro y Gato implementan esta interfaz y proporcionan sus propias implementaciones.
Uso de la interfaz
Abstracción en la práctica
La abstracción te permite ocultar los detalles innecesarios y simplificar el uso de objetos complejos. Algunas
aplicaciones comunes de la abstracción incluyen:
Interacción con objetos sin conocer sus detalles internos: En lugar de preocuparte por cómo está
implementado un objeto, solo usas los métodos expuestos por la interfaz o clase abstracta.
Definición de contratos (interfaces): Las interfaces permiten que diferentes clases implementen los
mismos métodos, pero con su propio comportamiento.
Ventajas de la Abstracción
Reducción de complejidad: Ayuda a que los sistemas sean más fáciles de entender y manejar.
Flexibilidad: Puedes cambiar la implementación interna de una clase sin afectar a otras partes del
programa que solo interactúan con su interfaz o métodos abstractos.
Reusabilidad: Las clases abstractas e interfaces pueden ser utilizadas por múltiples clases sin
necesidad de duplicar código.
Resumen de Abstracción en C#
La abstracción es el proceso de ocultar los detalles complejos y mostrar solo los aspectos esenciales.
Se logra en C# usando clases abstractas (que no se pueden instanciar directamente) e interfaces (que
definen un contrato sin implementación).
Las clases derivadas deben implementar los métodos abstractos o de la interfaz para proporcionar un
comportamiento concreto.
La abstracción ayuda a reducir la complejidad, mejorar la flexibilidad y mantener el código limpio y
organizado.