Documentos de Académico
Documentos de Profesional
Documentos de Cultura
➔ El estado de un objeto es el conjunto de valores internos que un objeto tiene, que representa
la situación en que está. El estado puede ser observable, sí el objeto permite que sea
conocido por otros objetos de la aplicación, u oculto, si no se permite verlo desde otros
objetos.
➔ El comportamiento de un objeto es el conjunto de respuestas que un método exhibe ante
solicitudes de otros objetos. En algunos casos, el comportamiento depende del estado en que
se encuentre dicho objeto.
➔ La identidad de un objeto es lo que lo diferencia de los demás objetos de su clase. Por
ejemplo, el auto con matricula AB1234CD tiene una identidad que lo diferencia de los
demás autos de la misma marca, modelo y color; aún cuando tengan el mismo
comportamiento y estén en el mismo estado. La identidad se le otorga en el momento de la
creación del mismo y se mantiene durante toda la vida. Es independiente del estado y la
localización física.
Para acceder al estado observable de un objeto, se utilizan las propiedades, que se accede
mediante el nombre de la variable seguida de un puto y el nombre de la propiedad.
El comportamiento describe los estímulos y reacciones de un objeto, dicho de otro modo, los
servicios que brinda. Es la manera en que éste reacciona ante mensajes o estímulos recibidos,
básicamente enviando mensajes a otros objetos, respondiendo al que le envía el mensaje o
cambiando de estado. Las distintas formas de respuesta se denominan métodos y corresponden a
procedimientos y funciones. Para llamar a un método de un objeto se coloca el nombre de la
variable seguida de puto y el nombre del método con sus argumentos.
1
Material exclusivo para uso interno en la Escuela Técnica Nro 12
Cuando se invoca un método sobre un objeto o se le pide el valor de una propiedad, se dice que le
estamos pasando un mensaje.
Ejemplos:
else Método
return (false);
}
}
Un objeto se genera a partir de una clase. Puedo tener varios objetos cuya identidad sea diferente a
partir de una misma clase (recordar el ejemplo del auto). Aplicado a la clase anterior el objeto
creado se llama “ArregloDesordenado”
class Program
{
static ClaseArregloDesordenado ArregloDesordenado = new ClaseArregloDesordenado(10);
// Declaracion del objeto
Objeto
static ClaseArregloDesordenado ElArreglo = new ClaseArregloDesordenado(10);
static void Main(string[] args)
{
ArregloDesordenado.Top=10; // se modifica el valor de la propiedad Top
ArregloDesordenado.EstaLleno();//Se invoca el método del objeto EstaLleno
(mensaje)
ElArreglo.Top=10;
}
}
La variable Top va a poder recibir el mismo mensaje por ser instancia del mismo tipo
ClaseArregloDesordenado pero como representa objetos distintos (ArregloDesordenado y
2
Material exclusivo para uso interno en la Escuela Técnica Nro 12
ElArreglo), con una identidad distinta, se va a obtener distintos valores y resultados enviando los
mismos mensajes.
Las clases se pueden agrupar de alguna manera, habitualmente conocida como paquetes. Un
paquete es un agrupamiento que se hace primordialmente para ordenar las clases en un sistema
mediano o grande, y para resolver conflictos de nombres. Por eso, algunos lenguajes -como C++ y
C#- los llaman espacios de nombres. Por ejemplo el paquete System, contiene a la clase Console.
3
Material exclusivo para uso interno en la Escuela Técnica Nro 12
son tipos por valor. Esto significa que las variables de esos tipos son creadas en memoria (en la
pila) en el momento en que el programa pasa por la declaración de las mismas, y destruidas cuando
termina el ámbito en el cual han sido declaradas.
Una variable del tipo por referencia no contiene directamente los datos almacenados, sino la
dirección de memoria (la referencia) del lugar donde están los datos. La declaración de una variable
de un tipo por referencia no alcanza para guardar espacio para el mismo, sino que esto se hace
dinámicamente más tarde mediante una sentencia especial, que en C# y Java se denomina new.
Cualquier variable de un tipo por referencia puede tomar el valor nulo (en Java y C#, la constante
null) lo que significa que no está referenciando nada.
Cuando trabajamos con objetos, lo que suele interesar es la identidad, lo que diferencia a un objeto
particular de otro. Por eso, tiene sentido toda comparación entre objetos, realizada con == y con !=,
que sirve para saber si se trata del mismo objeto, no de si tiene el mismo contenido.
2. Programación y Diseño
2.1 Construcción de clases
Partamos de un ejemplo. Supongamos que tenemos que implementar un sistema bancario muy
simple. Si analizamos qué entidades aparecen en el dominio del problema, una de ellas sería sin
duda el concepto de cuenta.
La POO intenta convertir los objetos (no necesariamente físicos) del dominio del problema, en,
objetos del dominio de la solución. Esto significa que habría objetos de algún tipo como “cuenta”
en nuestra solución. Esto se lleva a cabo implementando una clase que llamaré CuentaBancaria,
que sirva de molde para crear los objetos concretos. Para garantizar que al crear una cuenta esta
tenga un número y un titular, y evitar que se creen cuentas sin número ni titular, es necesario que la
creación de objetos se produzca llamando al constructor. Una primera idea sería:
Es decir, estamos diciendo que cuando creemos un objeto CuentaBancaria, le vamos a pasar como
valores iniciales el numero de cuenta y el nombre del titular.
Otra cosa que debemos poder hacer es depositar dinero. Pensemos en un método Depositar().
4
Material exclusivo para uso interno en la Escuela Técnica Nro 12
También se debería poder extraer dinero. Aquí existe un punto crítico en nuestra implementación.
Podría no haber saldo suficiente en la cuenta. Por lo tanto, vamos a suponer que el método Extraer
me indique con un resultado booleano si se pudo o no hacer la extracción.
Por último, en toda cuenta bancaria es importante conocer el saldo, es decir, el dinero que quedó en
mi cuenta después de realizar las operaciones. La línea sería,
Console.WriteLine(cuenta.Saldo);
Implementación
Escribamos el código. A la clase Program agregarle una clase, que como vimos en el ejemplo se
llama CuentaBancaria.
Lo primero que debemos preguntarnos es qué datos internos va a necesitar almacenar un objeto
CuentaBancaria. De lo planteado anteriormente, resulta que el número de cuenta, el nombre del
titular y por supuesto, el saldo. Por lo tanto, los atributos de la clase se definen de la siguiente
manera:
public double Saldo{ //para consultar el saldo, nótese la diferencia entre minúscula atributo y
mayúscula propiedad
get{
return saldo;
set{
5
Material exclusivo para uso interno en la Escuela Técnica Nro 12
saldo=value;
Esta propiedad Saldo permite conocer el saldo, pero no en forma arbitraria. El saldo sólo podrá
alterarse por los depósitos y las extracciones. Una mejor definición de la propiedad sería entonces
hacerla de consulta solamente,
get{
return saldo;
saldo+=monto;
if(monto>saldo)
return false;
else{
saldo+=monto;
return true;
6
Material exclusivo para uso interno en la Escuela Técnica Nro 12
Anteriormente hablamos de la importancia del constructor, recuerden que dijimos que no podía
existir una cuenta bancaria sin número ni titular, es decir no puede existir un objeto que no contenga
valores en dichas propiedades.
Public CuentaBancaria(int n, string t){ //constructor. Posee el mismo nombre que la clase
numero=n;
titular=t;
saldo=0;
Una vez que tenemos escrito el código de la clase pasamos a la clase Program y generamos el
objeto asignándole valores a sus propiedades.
cuenta.Depositar(2000);
Console.WriteLine(cuenta.saldo);
Ejercicio
¿Se anima a modificar el programa para que incluya un Menu que me pida los datos de número de
cuenta, nombre y me permita depositar, extraer, ver el saldo y salir?
7
Material exclusivo para uso interno en la Escuela Técnica Nro 12
delimitan su definición. Cualquier intento de acceder desde fuera de la misma, provocará un error
de compilación, ya que fuera de la clase, el método, atributo o propiedad en cuestión, no existe.
Los atributos, propiedades y métodos públicos se pueden usar desde cualquier lado, dentro o fuera
de la clase en cuestión.
En C# se pueden definir también constructores de clase. Estos constructores se invocan una vez
para cada programa, antes de crear cualquier instancia de esa clase. A veces se los utiliza para
inicializar atributos de clase que no se pueden asignar directamente en el código fuente. Los
constructores de clase se declaran con la palabra static y sin poner un calificador de acceso, ya que
no se invocan directamente en el código de ningún programa. Por supuesto, tampoco tienen
parámetros. Un uso, quizá un poco avanzado, de los constructores de clase, es el siguiente:
supongamos que tenemos un atributo de clase que se debe inicializar utilizando un valor guardado
en un archivo externo. ¿dónde pondríamos el código que lee ese archivo? ¡Adivinó...en un
constructor de clase!
8
Material exclusivo para uso interno en la Escuela Técnica Nro 12
A los atributos por referencia se les puede colocar el modificador readonly pero eso sólo afectaría a
la referencia. En este caso, lo que no se va a poder hacer con el atributo es un nuevo new, que
cambiaría la referencia del atributo.
existe el modificador const para declarar constantes. El problema es que sólo se puede usar con
tipos por valor, y además debe colocarse el valor de la constante en el código junto con la
declaración del atributo. Por lo tanto no es el constructor donde se la asigna un valor, y tampoco
puede definirse en tiempo de ejecución.
Esto significa que una clase se debe referir a no más de una entidad del problema que se está
resolviendo, además de que debe poder explicarse qué representa dicha clase de una manera simple,
y en lo posible contener -la oración de la descripción- un sólo sujeto.
Por ejemplo, podemos tener una clase Factura que contenga datos de un cliente y una serie de
artículos, pero deberíamos trabajar con 3 clases: Factura, Artículo y Cliente.
Un rasgo característico de un mal diseño de clases es la aparición de clases sin estado (no tienen
atributos ni propiedades), o sin comportamiento (sin métodos, además de los get y set de
propiedades). Se las suele llamar clases degeneradas o anémicas. La clase es una entidad que provee
un conjunto de servicios y no se supone que una clase hace algo.
9
Material exclusivo para uso interno en la Escuela Técnica Nro 12
Si la solución del problema presenta restricciones, estas se deben expresar en los atributos y
debemos garantizar que no haya ningún método o propiedad que pueda alterar el cumplimiento de
la misma, para garantizar la simplicidad de la clase, es una buena práctica el separar el
cumplimiento de las restricciones en una clase aparte.
return true;
boolean bisiesto=bisieso();
return 30;
Quedaría mejor si simplificamos las complejas condiciones lógicas y convertir la cantidad de días
por mes en una tabla:
10
Material exclusivo para uso interno en la Escuela Técnica Nro 12
return (anio%n==0);
if(anioMultiploDe(400))
return true;
return true;
int diasMes[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int dias=diasMes[mes];
dias=29;
return dias;
Ejercicios
Otra cuestión del diseño de métodos es evitar el código duplicado. Si parte del código de un método
es similar a una parte del de otro método, deberíamos hacer nuestro mayor esfuerzo para lograr
construir un método -privado- que sea llamado desde ambos, con los parámetros que sean
necesarios.
11
Material exclusivo para uso interno en la Escuela Técnica Nro 12
Evitar que la llamada desde un método publico implique la necesidad de llamar a otro método
también publico. De alguna manera cuando implementamos cosas así estamos violando el
ocultamiento ya que es obligatorio que conozcamos aspectos internos de los métodos, y sus
interrelaciones. La única excepción a esta regla son los constructores, que deben ser llamados antes
de cualquier otro método para cada instancia.
2.7 Conclusiones
El encapsulamiento o la conjunción de abstracción más ocultamiento de la implementación, es uno
de los pilares de la POO. Al poner juntos el comportamiento y los atributos, evitamos errores. Esto
permite aumentar la complejidad de los sistemas sin abrumar al cliente de la clase. Vimos que el
concepto principal de la POO es el de clase, que nos sirve tanto como tipo definido por el
programador como conjunto de objetos. Si bien se utilizan objetos, estos deben ser instancias de
clases definidas previamente.
12
Material exclusivo para uso interno en la Escuela Técnica Nro 12
3. Delegación
Veamos a través de un ejemplo. Supongamos que se quiere informatizar un club de inmobiliarias
que tiene inmuebles y clientes., de forma tal que los clientes puedan mostrar interés, reservar y
comprar un inmueble independientemente de la inmobiliaria que lo esté ofreciendo. Si un inmueble
cambia su precio se debe avisar a todos los clientes que mostraron su interés en él. Si un inmueble
se saca del mercado, se deberá avisar a todos los interesados.
El problema a resolver será crear el modelo de clases e implementar una parte del comportamiento
deseado.
En el diagrama Inmobiliaria e Inmueble son clases, nombre y superficie son atributos, AvisarVenta
y Vender son métodos. Los atributos, métodos y propiedades que están precedidos de un guión
(signo menos, -) son privados, mientras los que siguen a un signo más (+) son públicos. De cada
método, atributo y propiedad se puede indicar su tipo, como el caso del atributo email cuyo tipo es
string.
Las líneas que vinculan clases se llaman asociaciones, y en términos de programación significan
que una clase tiene un atributo cuyo tipo es la otra clase. Las flechasen esas líneas indican el sentido
de navegación de la relación, es decir, cuál es la clase que contiene el atributo (origen de la flecha) y
cuál la del tipo atributo (extremo de la flecha). Las asociaciones pueden tener cardinalidad, lo cual
indica de cuántos atributos estamos hablando. Por ejemplo, en el diagrama, la asociación entre
Inmobiliaria e Inmueble tiene un 1 y un *, que indican que por cada inmobiliaria hay varios
inmuebles.
13
Material exclusivo para uso interno en la Escuela Técnica Nro 12
Inmobiliaria
- nombre: string
+ AgregarInmueble (p: Inmueble)
+ QuitarInmueble (p: Inmueble)
+ImprimirDatos()
1
*
Inmueble
- domicilio: string
- superficie: double
- cantAmbientes: int
- precio: int
- reservado: bool
- vendido: bool
+ AnotarInteresado (c: Cliente)
+ EliminarInteresado (c: Cliente)
+ Reservar()
+ Vender()
+ ImprimirDatos()
1
Cliente
- nombre: string
- telefono: string
- email: string
+ AvisarCambioPrecio()
+ AvisarVenta (p: Inmueble)
+ AvisarReserva (p: Inmueble)
14
Material exclusivo para uso interno en la Escuela Técnica Nro 12
15
Material exclusivo para uso interno en la Escuela Técnica Nro 12
//Impresión básicamente
boyaca.ImprimirDatos();
Console.WriteLine();
//carga de inmobiliarias
sucasa.AgregarInmueble(membrillar);
sucasa.AgregarInmueble(neuquen);
flores.AgregarInmobiliaria(boyaca);
flores.AgregarInmueble(artigas);
//carga de interesados
membrillar.AnotarInteresado(ana);
artigas.AnotarInteresado(ana);
boyaca.AnotarInteresado(joaquin);
neuquen.AnotarInteresado(joaquin);
boyaca.AnotarInteresado(clara);
16
Material exclusivo para uso interno en la Escuela Técnica Nro 12
sucasa.ImprimirDatos();
flores.ImprimirDatos();
//movimientos
membrillar.Precio=92500;
membrillar.Reservar();
membrillar.Vender();
neuquen.EliminarInteresado(joaquin);
nequen.ElimiarInteresado(ana);
sucasa.ImprimirDatos();
flores.ImprimirDatos();
//fin
Console.ReadLine();
Con este programa como guía, vamos a intentar escribir las clases respectivas
IMPLEMENTACIÓN
17
Material exclusivo para uso interno en la Escuela Técnica Nro 12
this.nombre=nombre;
this.inmuebles=null;
this.cantidadInmuebles=0;
get{
return nombre;
get{
return cantidadInmuebles;
if(cantidadInmuebles==maximoInmuebles){
return;
if(Inmuebles==null)
inmuebles[cantidadInmuebles]=x;
cantidadInmuebles++;
18
Material exclusivo para uso interno en la Escuela Técnica Nro 12
if(inmuebles==null)
return;
if(pos>-1){
inmuebles[i]=inmuebles[i+1];
inmuebles[cantidadInmuebles-1]=null;
cantidadInmuebles--;
Console.WriteLine(“Inmobiliaria: ” + this.Nombre);
if(inmuebles!=null)
inmuebles[i].ImprimirDatos();
Console.WriteLine();
19
Material exclusivo para uso interno en la Escuela Técnica Nro 12
public Inmueble (string domicilio, double superficie, int cantidad Ambientes, int precio)
this.domicilio=domicilio;
this.superficie=superficie;
this.cantidadAmbientes=cantidadAmbientes;
this.precio=precio;
this.interesados=null;
this.reservado=false;
this.vendido=false;
get{
return domicilio;
20
Material exclusivo para uso interno en la Escuela Técnica Nro 12
get{
return superfice;
get{
return cantidadAmbientes;
get{
return precio;
set{
precio=value;
if(interesados != null)
if (cantidadInteresados == maximointeresados){
return;
21
Material exclusivo para uso interno en la Escuela Técnica Nro 12
if (interesados == null)
interesados[cantidadinteresados] = c;
cantidadInteresados++;
get{
return reservado;
reservado=true;
if (interesados != null)
interesados[i].AvisarReserva(this);
get{
return vendido;
vendido=true;
if(interesados != null)
22
Material exclusivo para uso interno en la Escuela Técnica Nro 12
interesados[i].AvisarVenta(this);
Console.WriteLine(“Domicilio: “ + Domicilio);
Console.WriteLine(“Superficie: “ + Superficie);
Console.WriteLine(“Precio: “ + Precio);
Console.WriteLine(“Reservado: “ + Reservado);
Console.WriteLine(“Vendido: “ + Vendido);
Console.WriteLine(Interesados[i].Nombre);
string nombre;
string teléfono;
string email;
this.nombre=nombre;
23
Material exclusivo para uso interno en la Escuela Técnica Nro 12
this.telefono=telefono;
this.email=email;
get{
return nombre;
get{
return teléfono;
get{
return email;
teléfono = nuevo;
email = nuevo;
24
Material exclusivo para uso interno en la Escuela Técnica Nro 12
string mensaje = “El Inmueble “ + x.Domicilio + “en el que estaba interesado ha cambiado
de precio. Hoy cuesta $” + nuevoPrecio;
string mensaje = “El Inmueble “ + x.Domicilio + “en el que estaba interesado ha sido
reservado”;
string mensaje = “El Inmueble “ + x.Domicilio + “en el que estaba interesado ha sido
vendido”;
Console.WriteLine(“Mail a “ +this.Nombre);
Console.WriteLine(evento);
Console.WriteLWritine(mensaje);
Console.WriteLine();
Un aspecto nuevo de este ejemplo es el uso de la clase Array, que tiene un método de clase IndexOf
para buscar un objeto en un arreglo, devolviendo su posición, o -1 si no se encuentra.
25
Material exclusivo para uso interno en la Escuela Técnica Nro 12
Lo novedoso de este ejemplo es que hemos usado algunas clases como tipo de algunos atributos de
otras clases. Por ejemplo, la clase Cliente es el tipo de los elementos del arreglo interesados,
atributo de la clase Inmueble. Lo mismo ocurre con la propia clase Inmueble, que la utilizamos
para definir el tipo de los elementos de un atributo de la clase Inmobiliaria.
El hecho de tener un atributo dentro de Inmobiliaria cuyo tipo sea Inmueble, nos habilita para
llamar métodos de clase Inmueble desde dentro de métodos de la clase Inmobiliaria, que invoca al
ImprimirDatos de Inmueble, utilizando el arreglo inmuebles.
26