Laboratorio 6
Tema 8. Programación Orientada a Objetos
Marco Teórico
En la vida real casi todo se compone de objetos (Carro, lapicero, casa, etc.). Entendemos que tanto un
Mercedes Benz verde, como un Corolla rojo son
carros
, pero son distintos en su aspecto físico, el color, la
potencia, el modelo, el año, etc. Sin embargo, ambos también tienen unas características comunes:
poseen ruedas, un volante, asientos... Esas características comunes son las que hacen pensar en el
concepto de
Carro
en ambos casos. A partir de ahora podemos interpretar que el Mercedes y el Corolla
son objetos, y el tipo o clase, de esos objetos es
Carro
.
Clases en Programación Orientada a Objetos (POO)
La clase reúne las característica de un objeto, cuando se les da valores a estas características entonces se
puede decir que se instancia un objeto. Por esto se dice que un objeto es la instancia de una clase.
Veamos: un
Carro
tiene 4 ruedas, 1 placa, 5 asientos; además un
Carro
acelera, frena y gira.
Las características de un
Carro
no solo dicen que cosas posee, sino que también describe qué acciones
puede realizar un Carro (acelerar, frenar y girar). Es decir, una clase define los atributos (que datos tiene
asociados) y las acciones o métodos (funcionalidades) que puede realizar un objeto de la clase.
Entonces decimos que:
Una
clase
define el comportamiento y atributos de un grupo de objetos con características
similares.
Los
atributos
determinan el
estado
del objeto. Son las características de los objetos. Cuando
definimos un atributo o propiedad normalmente especificamos su nombre y su tipo. Los atributos
son algo así como variables donde almacenamos datos relacionados con los objetos.
Los
métodos
definen el
comportamiento
del objeto. Son las funcionalidades asociadas a los
objetos.
De manera formal una clase se define de la siguiente forma:
Pseudoformal Clase <NombreDeLaClase>//Declaración de los atributos de la clase
<ModoDeAcceso> <TipoDeDato1> <ListaDeAtributosDeTipo1>; ...
<ModoDeAcceso> <TipoDeDatoN> <ListaDeAtributosDeTipoN>; //Declaración de los métodos de la clase
<ModoDeAcceso> Acción/Función <Método_i> (<ListaDeParámetros>) <InstruccionesDelMétodo_i>;
C++ class nombre_clase { <ModoDeAcceso>: <tipo> atributo_1; <tipo> atributo_n; <ModoDeAcceso>:
tipo método (lista de parámetros) { // cuerpo del método
}
//pueden haber n métodos …
};
Donde
<atributo_i>se define siguiendo la sintaxis ya manejada para la declaración de variables, y
<método_i>se define utilizando la sintaxis ya conocida para la declaración de acciones y funciones en C++.
En cuanto al
modo de acceso de los atributos y los métodos
, pueden ser:
Public
(publico): vistos o modificados desde cualquier clase.
Protected
(protegidos): solo pueden ser vistos o modificados desde la clase que los define y sus clases
hijas (Herencia, a tratar en el próximo laboratorio).
Private
(privado): Solo puede ser accedidos por la clase que los define.
Objetos en POO
Los objetos son ejemplares de una clase cualquiera. Cuando creamos un ejemplar tenemos que especificar la clase
a partir de la cual se creará. Esta acción de crear un objeto a partir de una clase se llama instanciar (que viene de
una mala traducción de la palabra instace que en inglés significa ejemplar). Por ejemplo, un objeto de la clase Carro
es por ejemplo Corolla. El concepto o definición de
Carro
sería la clase, pero cuando se habla de un Carro en
concreto, lo llamamos objeto.
¿Cómo se declara un objeto de una clase?
Para crear un nuevo objeto de una clase en C++, simplemente basta con indicar la
Clase
de la cual se quiere
instanciar el
objeto
y el nombre de este último, esta acción automáticamente realiza una llamada al
constructor de
la clase.
Ejemplo: nombre_clase nombre_objeto;
Una vez instanciado un objeto, este es tratado como una variable más dentro del código del programa. Puede ser un
parámetro de una función y.
Constructor de una Clase
El constructor es un método invocado o “llamado” cuando se instancia un objeto de una clase, y permite inicializar los
atributos del objeto (dentro de los paréntesis podríamos colocar parámetros con los que inicializar el objeto de la
clase Carro). El constructor es un método de acceso público que
tiene el mismo nombre de la clase
.
Pseudoformal Constructor (<ListaDeAtributos>) //Secuencia de Instrucciones FConstructor; C++ class Ejemplo { public: int a, b; Ejemplo(int c) { b = c; a = b + 3; };
Estado de un Objeto
Cuando tenemos un objeto sus propiedades toman valores. Por ejemplo, cuando tenemos un Carro la propiedad
color tomará un valor en concreto, como por ejemplo rojo o gris metalizado. El valor concreto de una propiedad de un
objeto se llama estado.
Para acceder a un estado de un objeto para ver su valor o cambiarlo se utiliza el operador punto.
miCarro.color = rojo
El objeto es
miCarro
, luego colocamos el operador punto y por último el nombre e la propiedad a la que deseamos
acceder. En este ejemplo estamos cambiando el valor del estado de la propiedad del objeto a rojo con una simple
asignación.
Nota:
Cabe destacar que para acceder a los atributos de un objeto de la manera antes vista estos deben tener un
modo de acceso
público.
Sin embargo es considerada una buena práctica de programación el que los atributos de una clase tengan modo de
acceso
privado
, y estos sean accedidos por métodos get
y
set (públicos)
.
Esto quiere decir que por cada atributo
de la clase debería existir un método
getAtributo(),
el cuál es una función que retorna el valor actual del dicho
atributo; y un método
setAtributo(valor),
el cual normalmente es una acción que modifica dicho atributo asignándole
el valor pasado por parámetro.
Ejemplo:
class Carro { // atributos private: // privados string color; int cant_ruedas; // métodos public: // públicosCarro(string c,int cc) { // método Constructor color=c; cant_ruedas=cc;
// métodos para obtener el valor de los atributos (Geters) y
// métodos para asignar un valor a los atributos (Seters)
string getColor(){ return color; } void setColor(string c){ color=c; } int getColor(){ return cant_ruedas; } void setColor(int cc){ cant_ruedas=cc; } } ;
Mensajes en objetos
Un mensaje en un objeto es la acción de efectuar una llamada a un método. Por ejemplo, cuando le decimos a un
objeto Carro que se ponga en marcha estamos pasándole el mensaje “ponte en marcha”.
Para mandar mensajes a los objetos utilizamos el operador
punto
, seguido del método que deseamos invocar.
miCarro.ponerseEnMarcha()
En este ejemplo pasamos el mensaje ponerseEnMarcha(). Hay que colocar paréntesis igual que cualquier llamada a
una función, dentro irían los parámetros.
Siguiendo con nuestro ejemplo:
class Carro
{ // implementa atributos y métodos generales de un carro // atributos o principales características del carro
private: // privados
String modelo, color, placa; Int Cant_Ruedas, Cant_Asientos; bool estacionado;
// métodos o principales operaciones del carro public: // públicos
Carro (string m, col, p, int ruedas, asientos) {
// método constructor modelo = m; placa = p;
Cant_Ruedas = ruedas; Cant_Asientos = asientos; color=col; estacionado=false;
// Acá se declararían todos y cada uno de los
// métodos para obtener el valor de los atributos (Geters) y
// métodos para asignar un valor a los atributos (Seters)
//
…
}; // fin de la declaración de la Clase Carro // acción adicional a la clase Carro.
// ella utiliza un objeto de la clase, llamado A y pasado por parámetro, // para simular como se estaciona un carro
void Estacionar(Carro &A)
{
cout<<”Se ha estacionado el carro ”<<A.getModelo()<<” ”<<A.getColor(); A.setEstacionado(true);
}
int main() { // acción principal del programa
// declaración del objeto C, de la clase carro, e inicialización de sus atributos Carro C (“corolla”,”rojo”, “YBJ-715”, 4, 5); // llamada al constructor de la clase // consultando mediante los métodos los valores de los atributos
cout << C.getModelo() << ” ” <<C.getPlaca() << ” “ << C.getColor() << ” “ << C.getCant_Ruedas() << ” “ << C. getCant_Asientos();
// se verifica si El carro NO está estacionado, en caso afirmativo se estaciona. if (!C.getEstacionado() ) { // si el carro C no está estacionado, se estaciona.
Estacionar(C); } else {
cout << ” El carro ya está estacionado”; }
return 0; // al llegar al retorno suele indicar que se ejecutó exitosamente la acción }
Relación de Herencia (Generalización / Especialización, Es un)
Es un tipo de jerarquía de clases, en la que cada subclase contiene los atributos y métodos de una (herencia simple)
o más superclases (herencia múltiple).
Mediante la herencia las instancias de una clase hija (o subclase) pueden acceder tanto a los atributos como a los
métodos públicos y protegidos de la clase padre (o superclase). Cada subclase o clase hija en la jerarquía es
siempre una extensión (esto es, conjunto estrictamente más grande) de la(s) superclase(s) o clase(s) padre(s) y
además incorporar atributos y métodos propios, que a su vez serán heredados por sus hijas.
Pseudoformal
Clase <NombreDeLaClasePadre>
//Declaración de los atributos de la clase
<ModoDeAcceso> <TipoDeDato_1> <ListaDeAtributosDeTipo_1>; ...
<ModoDeAcceso> <TipoDeDato_N> <ListaDeAtributosDeTipo_N>;
//Declaración de los métodos de la clase
<ModoDeAcceso> Acción/Función <Método_N> (<ListaDeParámetros>) <InstruccionesDelMétodo>
Facción / FFunción; FClase;
Clase <NombreDeLaClaseHija> Hereda de <NombreDeLaClasePadre>
//Declaración de los atributos de la clase
<ModoDeAcceso> <TipoDeDato_1> <ListaDeAtributosDeTipo_1>; ...
<ModoDeAcceso> <TipoDeDato_N> <ListaDeAtributosDeTipo_N>;
//Declaración de los métodos de la clase
<ModoDeAcceso> Acción/Función <Método_N> (<ListaDeParámetros>) <InstruccionesDelMétodo> Facción / FFunción; FClase;
C++
class nombre_clase_padre { <ModoDeAcceso>: <tipo> atributo_1; <tipo> atributo_n; <ModoDeAcceso>:tipo método (lista de parámetros) { // cuerpo del método
}
//pueden haber n métodos …
};
class nombre_clase_hija public: nombre_clase_padre
{
<tipo> atributo_1; <tipo> atributo_n;
<ModoDeAcceso>:
tipo método (lista de parámetros) { // cuerpo del método
}
//pueden haber n métodos …
};
Cabe resaltar que el lenguaje C++ Soporta
Herencia Múltiple.
Lo que quiere decir que la clase hija puede heredar
de varias clases padre. Este es un aspecto que a pesar de estar contemplado en el paradigma de Programación
Orientado a Objetos, es soportado por muy pocos lenguajes de programación.
En C++ la herencia múltiple se define de la siguiente manera:
C++
class nombre_clase_hija public: nombre_clase_padre1, nombre_clase_padre2
{ <ModoDeAcceso>: <tipo> atributo_1; <tipo> atributo_n; <ModoDeAcceso>:
tipo método (lista de parámetros) { // cuerpo del método
}
//pueden haber n métodos … };