Introducción al encapsulamiento
Uno de los pilares fundamentales de la programación orientada a objetos es el encapsulamiento, que consiste en ocultar los detalles internos de una clase y exponer únicamente lo necesario para su uso externo. En C++, esto se logra utilizando modificadores de acceso, que determinan qué partes del programa pueden acceder a los miembros (atributos y métodos) de una clase.
El encapsulamiento permite:
- Proteger el estado interno del objeto de modificaciones indebidas.
- Restringir el acceso directo a los atributos. Utilizamos métodos especiales (gettes y setters) par ael acceso y modificación de los atributos.
- Definir una interfaz pública clara, mientras se ocultan los detalles de implementación.
Modificadores de acceso
Los modificadores de acceso determinan la visibilidad de los atributos y métodos de la clase. Los más utilizados son:
public: Los miembros declarados comopublicson accesibles desde cualquier parte del programa.private: Los miembros declarados comoprivatesolo son accesibles desde dentro de la propia clase. Se utilizan para proteger el estado interno del objeto.
Veamos el mismo ejemplo que en el apartado anterior, pero ocultando los atributos:
#include <iostream>
class Rectangulo {
private:
double base;
double altura;
public:
// Constructor por defecto
Rectangulo() {
base = 0.0;
altura = 0.0;
}
// Constructor con parámetros
Rectangulo(double b, double h) {
base = b;
altura = h;
}
// Método para calcular el área
double calcularArea() const {
return base * altura;
}
};
int main() {
// Crear un objeto usando el constructor por defecto
Rectangulo r1;
std::cout << "Área del rectángulo r1 (por defecto): " << r1.calcularArea() << std::endl;
// Crear un objeto usando el constructor con parámetros
Rectangulo r2{5.0, 3.0};
std::cout << "Área del rectángulo r2 (con parámetros): " << r2.calcularArea() << std::endl;
// Modificar las dimensiones de r1 usando los setters
r1.setBase(7.0);
r1.setAltura(4.0);
std::cout << "Área del rectángulo r1 después de actualizar dimensiones: " << r1.calcularArea() << std::endl;
return 0;
}
Introducción de getters y setters
El encapsulamiento es un principio fundamental de la POO que consiste en proteger los atributos internos de los objetos, permitiendo su acceso o modificación únicamente a través de métodos públicos controlados, conocidos como getters (métodos que permiten el valor de los atributos) y setters (métodos que permiten modificar los atributos).
Veamos el ejemplo:
#include <iostream>
class Rectangulo {
private:
double base;
double altura;
public:
// Constructor por defecto
Rectangulo() {
base = 0.0;
altura = 0.0;
}
// Constructor con parámetros
Rectangulo(double b, double h) {
base = b;
altura = h;
}
// Métodos setters
void setBase(double b) {
base = b;
}
void setAltura(double h) {
altura = h;
}
// Métodos getters
double getBase() const {
return base;
}
double getAltura() const {
return altura;
}
// Método para calcular el área
double calcularArea() const {
return base * altura;
}
};
int main() {
// Crear un objeto usando el constructor por defecto
Rectangulo r1;
// Usar los setters para asignar valores
r1.setBase(7.0);
r1.setAltura(4.0);
// Usar los getters para obtener los valores de base y altura y mostrar el área
std::cout << "Área del rectángulo r1 (por defecto, luego usando setters): "
<< r1.calcularArea() << " (Base: " << r1.getBase()
<< ", Altura: " << r1.getAltura() << ")" << std::endl;
// Crear un objeto usando el constructor con parámetros
Rectangulo r2{5.0, 3.0}; // Inicialización uniforme
// Usar los getters para obtener los valores de base y altura y mostrar el área
std::cout << "Área del rectángulo r2 (con parámetros): "
<< r2.calcularArea() << " (Base: " << r2.getBase()
<< ", Altura: " << r2.getAltura() << ")" << std::endl;
// Modificar las dimensiones de r2 usando los setters
r2.setBase(10.0);
r2.setAltura(2.0);
// Usar los getters para obtener los valores de base y altura y mostrar el área
std::cout << "Área del rectángulo r2 después de actualizar dimensiones con setters: "
<< r2.calcularArea() << " (Base: " << r2.getBase()
<< ", Altura: " << r2.getAltura() << ")" << std::endl;
return 0;
}
Los getters y setters:
- Permiten controlar cómo se accede o modifica el estado del objeto.
- Facilitan la validación de datos antes de modificar atributos (como en el caso de la edad).
- Mejoran la seguridad y robustez del código.
- Mantienen el principio de encapsulamiento.
Ejemplo completo: Clase Coche
#include <iostream>
#include <string>
class Coche {
private:
std::string marca;
std::string modelo;
int anio;
public:
// Setter para la marca
void setMarca(const std::string& m) {
marca = m;
}
// Getter para la marca
std::string getMarca() const {
return marca;
}
// Setter para el modelo
void setModelo(const std::string& mod) {
modelo = mod;
}
// Getter para el modelo
std::string getModelo() const {
return modelo;
}
// Setter para el año (con validación)
void setAnio(int a) {
if (a > 1885) { // Primer automóvil se inventó alrededor de 1886
anio = a;
} else {
std::cout << "Año no válido. Debe ser mayor a 1885." << std::endl;
}
}
// Getter para el año
int getAnio() const {
return anio;
}
// Método para mostrar la información del coche
void mostrarInformacion() const {
std::cout << "Marca: " << marca
<< ", Modelo: " << modelo
<< ", Año: " << anio << std::endl;
}
};
int main() {
Coche coche1;
// Inicialización de los atributos usando setters
coche1.setMarca("Toyota");
coche1.setModelo("Corolla");
coche1.setAnio(2020);
// Mostrar información usando un método
coche1.mostrarInformacion();
// Ejemplo de uso de getters
std::cout << "La marca del coche es: " << coche1.getMarca() << std::endl;
return 0;
}
- La clase
Cocheencapsula tres atributos privados:marca,modeloyanio. - Se proporcionan métodos públicos (
setyget) para controlar el acceso y modificación de esos atributos. - El método
setAnioincluye una validación para evitar valores inválidos. - El método
mostrarInformacionimprime el estado del objeto de forma legible. - En la función
main, se crea un objetocoche1, se inicializa mediante setters y se accede a su información.