Diferencia Entre Una Clase Y Un Objeto
aamandavaron3 de Marzo de 2014
3.783 Palabras (16 Páginas)640 Visitas
Preguntas generadoras
• ¿Cuál es la diferencia entre una Clase y un Objeto?
Una clase es la definición de un tipo de objeto. Esta definición explica cuales métodos y atributos tiene un objeto de esta clase. Por lo tanto un objeto es una realización o instancia de una clase.
Si desarrollamos un programa de ordenador para nuestro concesionario, solo habrá una clase automóvil, es decir una sola definición, pero en la memoria puede haber ninguno, uno o varios objetos de clase automóvil, existiendo en un momento dado.
Distinguir entre clases, objetos y constructores puede ser confuso. Entender las diferencias entre estos términos es importante para saber cuando estámos diseñando un objeto y cuando estámos creando un objeto, y cómo se construyen nuestros objetos.
Las clases y objetos son los fundamentos de la programación Java. Todos los objetos están basados en clases. Una clase es una receta o plano de un objeto. Las clases especifican lo siguiente:
• Los datos (a través de campos, atributos, o variables).
• Cómo manipular los datos (a través de métodos).
• Cómo construir, o ejemplarizar, el objeto (opcional).
Una clase es una plantilla que define un objeto de la misma forma que una receta define nuestra comida favorita. Una clase no es un objeto igual que una receta de una tarta de manzada no es una tarta.
Supongamos que escribimos una clase llamada BankAccount que especifica los datos:
double account = 0; String name = "";
Definimos métodos que operan sobre los datos. Para usar esta clase, creamos un ejemplar de la clase llamado al constructor. El constructor es un método especial que crea un objeto de la clase desde donde es llamado. Por ejemplo:
BankAccount ba = new BankAccount()
Crea un objeto BankAccount .
Los constructores podrían incluir parámetros, por eso si se ejemplariza un objeto, es ejemplarizado con los argumentos suministrados.
En el ejemplo anterior BankAccount se inicializó sin ningún parámetro. Pero la clase puede especificar que el constructor acepte parámetros:
BankAccount(double account, String name) { account = account; customername = name; }
Cuando se ejemplariza BankAccount con BankAccount ba1 = new BankAccount(900, "Jane Doe") . Este objeto BankAccount ba1 tiene un saldo y un nombre que van con la cuenta.
Podemos crear tantos constructores como necesitemos. Si no escribirmos un constructor, se proporciona automáticamente un constructor por defecto igual que el primer constructor mostrado arriba en BankAccount(){} . El constructor por defecto ejemplariza un objeto sin parámetros.
La documentación de J2SE detalla como ejemplarizar objetos de las clases predefinidas en la librería llamando a su constructor o constructores.
Por ejemplo, consideremos el siguiente párrafo de la documentación del J2SE:
FileInputStream(File file) // constructor
Crea un FileInputStream abriendo una conexión a un fichero real, el fichero nombrado por el objeto File en el sistema de ficheros.
Si queremos usar este FileInputStream , ejemplarizamos la clase llamando a su constructor:
FileInputStream fin = new FileInputStream("bankaccount.dat");
• ¿En qué consiste el encapsulamiento?
Encapsulación:
También conocida como ocultamiento. Cuando me acuesto a ver televisión no me preocupo del modo como éste funciona, o lo que hace para cambiar de canal o aumentar el volumen. A menos que seas experto en electrónica o técnico en televisores, te pasará lo mismo: no lo sabes y no te importa; sólo sabes que al presionar un botón ocurre la magia.
La encapsulación se encarga de mantener ocultos los procesos internos que necesita para hacer lo que sea que haga, dándole al programador acceso sólo a lo que necesita. Esto da dos ventajas iniciales: Lo que hace el usuario puede ser controlado internamente (incluso sus errores), evitando que todo colapse por una intervención indeseada (tú no quieres que tu mamá, que no tiene ni idea de electrónica, abra tu televisor y empiece a jugar con los circuitos para cambiar los canales manualmente ¿verdad?). La segunda ventaja es que, al hacer que la mayor parte del código esté oculto, puedes hacer cambios y/o mejoras sin que eso afecte el modo como los usuarios van a utilizar tu código. Sólo tienes que mantener igual la forma de acceder a él (en el caso del control de la tele, que los botones sigan siendo los mismos y que el botón de “apagado” no cambie el volumen). Por cierto, estas puertas de acceso que das a los usuarios son lo que se conoce como interfaz.(7)
Encapsulamiento de los atributos de una clase
Antes de nada, debe quedar claro que el encapsulamiento, igual que cualquier buen hábito de programación (como no poner goto, comentar, etc) es útil para código que más adelante se puede querer reutilizar o modificar, por otras personas o por uno mismo. Si yo hago un programa de marcianos y nunca jamas pienso volver a tocarlo, da igual que lo haga con gotos y sin comentar mientras me entere yo mismo mientras lo estoy haciendo y funcione. Pagaré este "pecado" si dentro de dos meses se me ocurre mejorarlo o quiero reaprovechar algo de su código para otro programa.
Comento esto porque el encapsulamiento, llevado a su extremo, como es el caso del punto final de interfaces, hace la programación un poco más complicada (hay que hacer más clases). Este esfuerzo sólo se ve recompensado si el código es muy grande (evitando recompilados innecesarios) o se va a reutilizar en un futuro (podremos extraer clases con menos dependencias de otras clases). Dicho esto, vamos al tema.
Cualquier curso de orientación a objetos nos dice que es mejor poner los atributos de una clase protegidos o privados (nunca públicos) y acceder a ellos a través de métodos públicos que pongamos en la clase. Veamos el motivo. Supongamos, por ejemplo, que nos piden un programa que permita llevar una lista de gente con sus fechas de nacimiento. Entre otras cosas, decidimos hacernos nuestra clase Fecha con varios métodos maravillosos de la siguiente manera.
class Fecha
{
public:
int anho; // El anho con cuatro cifras, ej. 2004
int mes; // El mes, de 1 a 12
int dia; // El dia, de 1 a 31
void metodoMaravilloso1();
void metodoMaravilloso2();
};
Ya hemos hecho la clase. Ahora hacemos el resto del código y en unos varios miles de líneas de código usamos directamente cosas como esta.
Fecha unaFecha;
unaFecha.anho = 2004;
unaFecha.mes = 1;
unaFecha.dia = 25;
Finalmente acabamos nuestro programa y todo funciona de maravilla. Unos días después nos dicen que el programa va a guardar tropecientas mil personas y que ocupan mucho los ficheros, que a ver si podemos hacer algo para remediarlo. ¡Vaya!, almacenamos una fecha con tres enteros. Si usamos el formato de la mayoría de los ordenadores, en el que la fecha es el número de segundos transcurridos desde el 1 de Enero de 1970 (lo que nos devuelve la función time()), basta con un entero.
Total, que manos a la obra, cambiamos nuestra clase para que tenga lo siguiente:
class Fecha
{
public:
/* Comentado por ineficiente
int anho;
int mes;
int dia; */
long numeroSegundos;
void metodoMaravilloso1();
void metodoMaravilloso2();
};
Ya está hecho lo fácil. Ahora sólo hay que ir por las tropecientas mil líneas de código cambiando nuestras asignaciones y lecturas a los tres enteros anteriores por el nuevo long.
Hubiera sido mucho mejor si hubieramos hecho estos tres enteros protegidos y unos métodos para acceder a ellos. Algo como esto
class Fecha
{
public:
void tomaFecha (int anho, int mes, int dia);
int dameAnho ();
int dameMes ();
int dameDia ();
void metodoMaravilloso1();
void metodoMaravilloso2();
protected:
int anho; // El anho con cuatro cifras, ej. 2004
int mes; // El mes, de 1 a 12
int dia; // El dia, de 1 a 31
};
Si ahora tenemos que hacer el mismo cambio, basta con cambiar los atributos protegidos. Los métodos tomaXXX() y dameXXX() se mantienen en cuanto a parámetros y valor devuelto, pero se modifica su código interno para que conviertan el año,mes y dia en un long de segundos y al revés. El resto del código no hay que tocarlo en absoluto.
Es incluso mejor hacer los atributos privados que protegidos. Haciéndolos protegidos, las clases hijas (las que heredan de Fecha) pueden acceder directamente a estos atributos. Cuando hagamos el cambio por un long, debemos cambiar también el código de las clases hijas. Si los atributos son privados y obligamos a las clases hijas a acceder a ellos a través de métodos, tampoco tendremos que cambiar el código de estas clases hijas.
El acceso a través de métodos es menos eficiente que hacerlo directamente, así que aunque siguiendo el principio de ocultación es mejor hacer atributos privados, por eficiencia en algunos casos quizás sea mejor hacerlos protegidos (o incluso públicos) a riesgo de tener que cambiar más líneas de código en caso de cambio.
Importancia de la encapsulación en C++
Con lo contado hasta ahora evitamos tener que cambiar código en caso
...