Está en la página 1de 37

S.E.P.

D.G.E.S.T
INSTITUTO TECNOLGICO DE CERRO AZUL

UNIDAD II: CLASES Y OBJETOS

PRESENTADO POR: Equipo #6

Gonzlez Santos Lzaro Jurez Constantino Julin Ismael Liborio Sobrevilla Abraham Isa Ramrez Cruz Vicente
CATEDRTICO: Ma. Teresa Cobos Ponce

ING. SISTEMAS COMPUTACIONALES

Introduccin En la unidad 1 se ha dado ha conocer las nociones bsicas de la sintaxis de Java. A partir de ahora es cuando entramos la verdadera potencia de Java como lenguaje orientado a objetos: las clases y los objetos. Durante todo este captulo se va a trabajar en la construccin de una clase MiPunto, que modeliza un punto en un espacio plano: class MiPunto{

int x, y;

int metodoSuma( int paramX, int paramY ) {

return ( paramX + paramY );

double distancia(int x, int y) {

int dx= this.x pX;

int dy = this.y pY;

return Math.sqrt(dx*dx + dy*dy);

void metodoVacio( ) { }

void inicia( int paramX, int paramY ) {

x = paramX;

y = paramY;

void inicia2( int x, int y ) {

x = x; // Ojo, no modificamos la variable de instancia!!!

this.y = y; // Modificamos la variable de instancia!!!

MiPunto( int paramX, int paramY ) {

this.x = paramX; // Este this se puede omitir

y = paramY; // No hace falta this

MiPunto() {

inicia(-1,-1); //Por defecto ; this(-1,-1) hace lo mismo

2.1.- Declaracin de clases a.) Introduccin El elemento bsico de la programacin orientada a objetos en Java es la clase. Una clase define la forma y comportamiento de un objeto. Para crear una clase slo se necesita un archivo fuente que contenga la palabra clave reservada class seguida de un identificador legal y un bloque delimitado por dos llaves para el cuerpo de la clase. class MiPunto { } Un archivo de Java debe tener el mismo nombre que la clase que contiene, y se les suele asignar la extensin ".java". Por ejemplo la clase MiPunto se guardara en un fichero que se llamase MiPunto.java. Hay que tener presente que en Java se diferencia entre maysculas y minsculas; el nombre de la clase y el de archivo fuente han de ser exactamente iguales. Aunque la clase MiPunto es sintcticamente correcta, es lo que se viene a llamar una clase vaca, es decir, una clase que no hace nada. Las clases tpicas de Java incluirn variables y mtodos de instancia. Los programas en Java completos constarn por lo general de varias clases de Java en distintos archivos fuente. Una clase es una plantilla para un objeto. Por lo tanto define la estructura de un objeto y su interfaz funcional, en forma de mtodos. Cuando se ejecuta un programa en Java, el sistema utiliza definiciones de clase para crear instancias de las clases, que son los objetos reales. Los trminos instancia y objeto se utilizan de manera indistinta. La forma general de una definicin de clase es: class Nombre_De_Clase {

tipo_de_variable nombre_de_atributo1;

tipo_de_variable nombre_de_atributo2;

// . . .

tipo_devuelto nombre_de_mtodo1( lista_de_parmetros ) {

cuerpo_del_mtodo1;

tipo_devuelto nombre_de_mtodo2( lista_de_parmetros ) {

cuerpo_del_mtodo2;

// . . .

Los tipos tipo_de_variable y tipo_devuelto, han de ser tipos simples Java o nombres de otras clases ya definidas. Tanto Nombre_De_Clase, como los nombre_de_atributo y nombre_de_mtodo, han de ser identificadores Java vlidos.

b.) Los atributos

Los datos se encapsulan dentro de una clase declarando variables dentro de las llaves de apertura y cierre de la declaracin de la clase, variables que se conocen como atributos. Se declaran igual que las variables locales de un mtodo en concreto. Por ejemplo, este es un programa que declara una clase MiPunto, con dos atributos enteros llamados x e y. class MiPunto {

int x, y;

Los atributos se pueden declarar con dos clases de tipos: un tipo simple Java (ya descritos), o el nombre de una clase (ser una referencia a objeto, vase el punto C.a de este mismo apartado). Cuando se realiza una instancia de una clase (creacin de un objeto) se reservar en la memoria un espacio para un conjunto de datos como el que definen los atributos de una clase. A este conjunto de variables se le denomina variables de instancia. c.) Los mtodos Los mtodos son subrutinas que definen la interfaz de una clase, sus capacidades y comportamiento. Un mtodo ha de tener por nombre cualquier identificador legal distinto de los ya utilizados por los nombres de la clase en que est definido. Los mtodos se declaran al mismo nivel que las variables de instancia dentro de una definicin de clase. En la declaracin de los mtodos se define el tipo de valor que devuelven y a una lista formal de parmetros de entrada, de sintaxis tipo identificador separadas por comas. La forma general de una declaracin de mtodo es: tipo_devuelto nombre_de_mtodo( lista-formal-de-parmetros ) {

cuerpo_del_mtodo;

Por ejemplo el siguiente mtodo devuelve la suma de dos enteros: int metodoSuma( int paramX, int paramY ) {

return ( paramX + paramY );

En el caso de que no se desee devolver ningn valor se deber indicar como tipo la palabra reservada void. As mismo, si no se desean parmetros, la declaracin del mtodo debera incluir un par de parntesis vacos (sinvoid): void metodoVacio( ) { }; Los mtodos son llamados indicando una instancia individual de la clase, que tendr su propio conjunto nico de variables de instancia, por lo que los mtodos se pueden referir directamente a ellas. El mtodo inicia() para establecer valores a las dos variables de instancia sera el siguiente: void inicia( int paramX, int paramY ) {

x = paramX;

y = paramY;

2.2.- Instanciacin de una clase

a.) Referencias a Objeto e Instancias Los tipos simples de Java describan el tamao y los valores de las variables. Cada vez que se crea una clase se aade otro tipo de dato que se puede utilizar igual que uno de los tipos simples. Por ello al declarar una nueva variable, se puede utilizar un nombre de clase como tipo. A estas variables se las conoce como referencias a objeto. Todas las referencias a objeto son compatibles tambin con las instancias de subclases de su tipo. Del mismo modo que es correcto asignar un byte a una variable declarada como int, se puede declarar que una variable es del tipo MiClase y guardar una referencia a una instancia de este tipo de clase: MiPunto p; Esta es una declaracin de una variable p que es una referencia a un objeto de la clase MiPunto, de momento con un valor por defecto de null. La referencia null es una referencia a un objeto de la clase Object, y se podr convertir a una referencia a cualquier otro objeto porque todos los objetos son hijos de la clase Object. b.) Constructores Las clases pueden implementar un mtodo especial llamado constructor. Un constructor es un mtodo que inicia un objeto inmediatamente despus de su creacin. De esta forma nos evitamos el tener que iniciar las variables explcitamente para su iniciacin. El constructor tiene exactamente el mismo nombre de la clase que lo implementa; no puede haber ningn otro mtodo que comparta su nombre con el de su clase. Una vez definido, se llamar automticamente al constructor al crear un objeto de esa clase (al utilizar el operador new). El constructor no devuelve ningn tipo, ni siquiera void. Su misin es iniciar todo estado interno de un objeto (sus atributos), haciendo que el objeto sea utilizable inmediatamente; reservando memoria para sus atributos, iniciando sus valores... Por ejemplo: MiPunto( ) {

inicia( -1, -1 );

Este constructor denominado constructor por defecto, por no tener parmetros, establece el valor -1 a las variables de instancia x e y de los objetos que construya. El compilador, por defecto ,llamar al constructor de la superclase Object() si no se especifican parmetros en el constructor. Este otro constructor, sin embargo, recibe dos parmetros: MiPunto( int paraX, int paraY ) {

inicia( paramX, paramY );

La lista de parmetros especificada despus del nombre de una clase en una sentencia new se utiliza para pasar parmetros al constructor. Se llama al mtodo constructor justo despus de crear la instancia y antes de que new devuelva el control al punto de la llamada. As, cuando ejecutamos el siguiente programa: MiPunto p1 = new MiPunto(10, 20); System.out.println( "p1.- x = " + p1.x + " y = " + p1.y ); Se muestra en la pantalla: p1.- x = 10 y = 20 Para crear un programa Java que contenga ese cdigo, se debe de crear una clase que contenga un mtodo main(). El intrprete java se ejecutar el mtodo main de la clase que se le indique como parmetro. Para ms informacin sobre cmo crear y ejecutar un programa, as como los tipos de programas que se pueden crear en Java, vase el captulo "II.12. Creacin de programas Java" de este tutorial. c.) El operador new El operador new crea una instancia de una clase (objetos) y devuelve una referencia a ese objeto. Por ejemplo: MiPunto p2 = new MiPunto(2,3);

Este es un ejemplo de la creacin de una instancia de MiPunto, que es controlador por la referencia a objeto p2. Hay una distincin crtica entre la forma de manipular los tipos simples y las clases en Java: Las referencias a objetos realmente no contienen a los objetos a los que referencian. De esta forma se pueden crear mltiples referencias al mismo objeto, como por ejemplo: MiPunto p3 =p2; Aunque tan slo se cre un objeto MiPunto, hay dos variables (p2 y p3) que lo referencian. Cualquier cambio realizado en el objeto referenciado por p2 afectar al objeto referenciado por p3. La asignacin de p2 a p3no reserva memoria ni modifica el objeto. De hecho, las asignaciones posteriores de p2 simplemente desengancharn p2 del objeto, sin afectarlo: p2 = null; // p3 todava apunta al objeto creado con new Aunque se haya asignado null a p2, p3 todava apunta al objeto creado por el operador new. Cuando ya no haya ninguna variable que haga referencia a un objeto, Java reclama automticamente la memoria utilizada por ese objeto, a lo que se denomina recogida de basura. Cuando se realiza una instancia de una clase (mediante new) se reserva en la memoria un espacio para un conjunto de datos como el que definen los atributos de la clase que se indica en la instanciacin. A este conjunto de variables se le denomina variables de instancia. La potencia de las variables de instancia es que se obtiene un conjunto distinto de ellas cada vez que se crea un objeto nuevo. Es importante el comprender que cada objeto tiene su propia copia de las variables de instancia de su clase, por lo que los cambios sobre las variables de instancia de un objeto no tienen efecto sobre las variables de instancia de otro. El siguiente programa crea dos objetos MiPunto y establece los valores de x e y de cada uno de ellos de manera independiente para mostrar que estn realmente separados. MiPunto p4 = new MiPunto( 10, 20 ); MiPunto p5 = new MiPunto( 42, 99 ); System.out.println("p4.- x = " + p4.x + " y = " + p4.y); System.out.println("p5.- x = " + p5.x + " y = " + p5.y); Este es el aspecto de salida cuando lo ejecutamos. p4.- x = 10 y = 20 p5.- x = 42 y = 99

2.3.- Referencia al objeto actual No se puede declarar instancias de clases usando el nombre de la clase y un nombre para el objeto (como se hace en C++). La declaracin ClassName ObjectName crea solamente una referencia a un objeto de dicho tipo. Para crear un objeto dinmico en el montn se usa el operador new con el constructor del objeto deseado. El operador devuelve una referencia al objeto creado. ClassName ObjectReference = new ClassName(...) Slo si una clase no contiene ningn constructor Java propone un constructor por defecto que tiene el mismo modificador de acceso que la clase. Constructores pueden lanzar excepciones como cualquier otro mtodo. Para facilitar la construccin de objetos an ms, es posible usar bloques de cdigo sin que pertenezcan a constructores. Esos bloques estn prepuestos (en su orden de aparencia) delante de los cdigos de todos los constructores. El mismo mecanismo se puede usar para inicializar miembros estticos poniendo un static delante del bloque de cdigo. Inicializaciones estticas no pueden lanzar excepciones. class ... { ... static int[] powertwo=new int[10]; static { powertwo[0]=1; for(int i=1; i<powertwo.length; i++) powertwo[i]=powertwo[i-1]<<1; } ... } Si una clase, por ejemplo, X, construye un miembro esttico de otra clase, por ejemplo, Y, y al revs, el bloque de inicializacin de X est ejecutado solamente hasta la aparencia de Y cuyos bloques de inicializacin recurren al X construido a medias. Nota que todas las variables en Java siempre estn en cero si todava no estn inicializadas explcitamente. No existe un operador para eliminar objetos del montn, eso es tarea del recolector de memoria incorporado en Java (diferencia con C++ donde se tiene que liberar memoria con delete explcitamente). Para dar pistas de ayuda al recolector se puede asignar null a una referencia indicando al recolector que no se va a referenciar dicho objeto nunca jams. Las referencias que todava no acceden a ningn objeto tienen el valor null.

Est permitida la conversin explcita de un tipo a otro mediante la reinterpretacin del tipo (``cast'') con todas sus posibles consecuencias. El ``cast'' es importante especialmente en su variante del ``downcast'', es decir, cuando se sabe que algn objeto es de cierto tipo derivado pero se tiene solamente una referencia a una de sus super-clases. Se puede comprobar el tipo actual de una referencia con el operador instanceof. if( refX instanceof refY ) { ... }

Acceso al objeto a.) El operador punto (.) El operador punto (.) se utiliza para acceder a las variables de instancia y los mtodos contenidos en un objeto, mediante su referencia a objeto: referencia_a_objeto.nombre_de_variable_de_instancia referencia_a_objeto.nombre_de_mtodo( lista-de-parmetros ); Hemos creado un ejemplo completo que combina los operadores new y punto para crear un objeto MiPunto, almacenar algunos valores en l e imprimir sus valores finales: MiPunto p6 = new MiPunto( 10, 20 ); System.out.println ("p6.- 1. X=" + p6.x + " , Y=" + p6.y); p6.inicia( 30, 40 ); System.out.println ("p6.- 2. X=" + p6.x + " , Y=" + p6.y); Cuando se ejecuta este programa, se observa la siguiente salida: p6.- 1. X=10 , Y=20 p6.- 2. X=30 , Y=40 Durante las impresiones (mtodo println()) se accede al valor de las variables mediante p6.x y p6.y, y entre una impresin y otra se llama al mtodo inicia(), cambiando los valores de las variables de instancia. Este es uno de los aspectos ms importantes de la diferencia entre la programacin orientada a objetos y la programacin estructurada. Cuando se llama al mtodo p6.inicia(), lo primero que se hace en el mtodo es sustituir los nombres de los atributos de la clase por las

correspondientes variables de instancia del objeto con que se ha llamado. As por ejemplo x se convertir en p6.x. Si otros objetos llaman a inicia(), incluso si lo hacen de una manera concurrente, no se producen efectos laterales, ya que las variables de instancia sobre las que trabajan son distintas. b.) La referencia this Java incluye un valor de referencia especial llamado this, que se utiliza dentro de cualquier mtodo para referirse al objeto actual. El valor this se refiere al objeto sobre el que ha sido llamado el mtodo actual. Se puede utilizar this siempre que se requiera una referencia a un objeto del tipo de una clase actual. Si hay dos objetos que utilicen el mismo cdigo, seleccionados a travs de otras instancias, cada uno tiene su propio valor nico dethis. Un refinamiento habitual es que un constructor llame a otro para construir la instancia correctamente. El siguiente constructor llama al constructor parametrizado MiPunto(x,y) para terminar de iniciar la instancia: MiPunto() {

this( -1, -1 ); // Llama al constructor parametrizado

En Java se permite declarar variables locales, incluyendo parmetros formales de mtodos, que se solapen con los nombres de las variables de instancia. No se utilizan x e y como nombres de parmetro para el mtodo inicia, porque ocultaran las variables de instancia x e y reales del mbito del mtodo. Si lo hubisemos hecho, entonces x se hubiera referido al parmetro formal, ocultando la variable de instancia x: void inicia2( int x, int y ) {

x = x; // Ojo, no modificamos la variable de instancia!!!

this.y = y; // Modificamos la variable de instancia!!! }

1.4.- Tipos de mtodos Objetivos: a) Profundizar en el concepto de mtodo de una clase e indicar los tipos de mtodos en Java: mtodos de instancia y mtodos de clase b) Interpretar el cdigo fuente de una aplicacin Java donde aparecen mtodos de distintos tipos c) Construir una aplicacin Java sencilla, convenientemente especificada, que emplee clases con diferentes mtodos. Un mtodo es una abstraccin de una operacin que puede hacer o realizarse con un objeto. Una clase puede declarar cualquier nmero de mtodos que lleven a cabo operaciones de lo ms variado con los objetos. En esta seccin los mtodos se clasifican en dos grupos: los mtodos de instancia y los mtodos de clase. Adems se cierra el captulo con los mtodos de clase o estticos de la clase Math. Mtodos de instancia Las clases pueden incluir en su declaracin muchos mtodos o no declarar ninguno. Los mtodos pueden clasificarse en mtodos de instancia y mtodos de clase. Los mtodos de instancia operan sobre las variables de instancia de los objetos pero tambin tienen acceso a las variables de clase. La sintaxis de llamada a un mtodo de instancia es: idReferencia.idMetodo(parametros); // Llamada tipica a un metodo de instancia Todas las instancias de una clase comparten la misma implementacin para un mtodo de instancia. La instancia que hace la llamada al mtodo es siempre un parmetro o argumento implcito. Dentro de un mtodo de instancia, el identificador de una variable de instancia hace referencia al atributo de la instancia concreta que hace la llamada al mtodo (suponiendo que el identificador del atributo no ha sido ocultado por el de un parmetro).

En el ejemplo anterior en la declaracin de la clase CuentaBancaria, los mtodos saldo y transferencia son mtodos de instancia. public double saldo() { return saldo; } public void transferencia( CuentaBancaria origen ) { saldo += origen.saldo; origen.saldo=0; } Ejemplos de llamada a estos mtodos dentro de PruebaCuentaBancaria: CuentaBancaria c1 = new CuentaBancaria(); CuentaBancaria c2 = new CuentaBancaria(20.0); c1.transferencia(c2); -Beltr 2.5.- Constructores y Destructores a.) La destruccin de los objetos Cuando un objeto no va a ser utilizado, el espacio de memoria de dinmica que utiliza ha de ser liberado, as como los recursos que posea, permitiendo al programa disponer de todos los recursos posibles. A esta accin se la da el nombre de destruccin del objeto. En Java la destruccin se puede realizar de forma automtica o de forma personalizada, en funcin de las caractersticas del objeto. b.) La destruccin por defecto: Recogida de basura El intrprete de Java posee un sistema de recogida de basura, que por lo general permite que no nos preocupemos de liberar la memoria asignada explcitamente. El recolector de basura ser el encargado de liberar una zona de memoria dinmica que haba sido reservada mediante el operador new, cuando el objeto ya no va a ser utilizado ms durante el programa (por ejemplo, sale del mbito de utilizacin, o no es referenciado nuevamente).

El sistema de recogida de basura se ejecuta peridicamente, buscando objetos que ya no estn referenciados. c.) La destruccin personalizada: finalice A veces una clase mantiene un recurso que no es de Java como un descriptor de archivo o un tipo de letra del sistema de ventanas. En este caso sera acertado el utilizar la finalizacin explcita, para asegurar que dicho recurso se libera. Esto se hace mediante la destruccin personalizada, un sistema similar a los destructores de C++. Para especificar una destruccin personalizada se aade un mtodo a la clase con el nombre finalize: class ClaseFinalizada{

ClaseFinalizada() { // Constructor

// Reserva del recurso no Java o recurso compartido

protected void finalize() {

// Liberacin del recurso no Java o recurso compartido

El intrprete de Java llama al mtodo finalize(), si existe cuando vaya a reclamar el espacio de ese objeto, mediante la recogida de basura. Debe observarse que el mtodo finalize() es de tipo protected void y por lo tanto deber de sobreescribirse con este mismo tipo.

2.6.-Sobrecarga de mtodos en Java Un mtodo sobrecargado se utiliza para reutilizar el nombre de un mtodo pero con diferentes argumentos (opcionalmente un tipo diferente de retorno). Las reglas para sobrecargar un mtodo son las siguientes: + Los mtodos sobrecargados debeb de cambiar la lista de argumentos. + Pueden cambiar el tipo de retorno. + Pueden cambiar el modificador de acceso. + Pueden declarar nuevas o ms amplias excepciones. + Un mtodo puede ser sobrecargado en la misma clase o en una subclase. Veamos un mtodo que se desea sobrecargar: public void cambiarTamano(int tamano, String nombre, float patron){ }Los siguientes mtodos son sobrecargas legales del mtodo cambiarTamano:)( public public public void cambiarTamano(int int cambiarTamano(int void cambiarTamano(float patron, tamano, String tamano, float String nombre) throws nombre){} patron){} IOException{}

Cmo

invocar

un

mtodo

sobrecargado:

Lo que define qu mtodo es el que se va a llamar son los argumentos que se envan al mismo durante la llamada. Si se invoca a un mtodo con un String como argumento, se ejecutar el mtodo que tome un String como argumento, si se manda a llamar al mismo mtodo pero con un float como argumento, se ejecutar el mtodo que tome un float como argumento y as sucesivamente. Si se invoca a un mtodo con un argumento que no es definido en ninguna de las versiones sobrecargadas entonces el compilador arrojar un mensaje de error. Ejemplo de una clase con un mtodo sobrecargado:

public class Sobrecarga { public void Numeros(int x, int y){ System.out.println("Mtodo que recibe enteros."); } public void Numeros(double x, double y){ System.out.println("Mtodo que recibe flotantes."); } public void Numeros(String cadena){ System.out.println("Mtodo que recibe una cadena: "+ cadena); } public static void main (String... args){

Sobrecarga s int int s.Numeros(a,b); s.Numeros(3.2,5.7); s.Numeros("Monillo007"); } } Al Mtodo Mtodo Mtodo ejecutar el

= a b

new = =

Sobrecarga(); 1; 2;

cdigo que que recibe

anterior

obtendremos recibe recibe

lo

siguiente: enteros. flotantes. Monillo007

que

una

cadena:

Al utilizar objetos en lugar de tipos primitivos o cadenas se vuelve ms interesante. Veamos lo que sucede cuando se tiene un mtodo sobrecargado que en una de sus versiones toma un Animal como parmetro y en otra un Caballo. class class Caballo Animal extends { Animal{ } } Animales{ a){ Animal..."); c){ Caballo..."); args){ Animales(); Animal(); Caballo();

class public void MetodoSobrecargado(Animal System.out.println("Mtodo de parmetro } public void MetodoSobrecargado(Caballo System.out.println("Mtodo de parmetro } public static void main(String... Animales as = new Animal objetoAnimal = new Caballo objetoCaballo = new as.MetodoSobrecargado(objetoAnimal); as.MetodoSobrecargado(objetoCaballo); } } Al Mtodo Mtodo ejecutar de de el cdigo anterior parmetro parmetro

obtenemos: Animal... Caballo...

Como era de esperarse, cada objeto manda a llamar al mtodo que le corresponde de acuerdo a su tipo, pero qu pasa si creamos una referencia Animal sobre un objeto Caballo... Animal objetoAnimalRefCaballo as.MetodoSobrecargado(objetoAnimalRefCaballo); El Mtodo de resultado parmetro = new Caballo();

es: Animal...

Aunque en tiempo de ejecucin el objeto es un Caballo y no un Animal, la eleccin de qu mtodo sobrecargado invocar no se realiza dinmicamente en tiempo de ejecucin, el tipo de referencia, no el objeto actual, es el que determina qu mtodo es el que se ejecutar. Reglas de la sobrecarga y sobreescritura de mtodos::

Ahora que hemos visto ambas formas de reescribir mtodos, revisemos las reglas y diferencias entre ambos tipos de reescritura: +Argumentos: En un mtodo sobrecargado los argumentos deben de cambiar mientras que en un mtodo sobreescrito NO deben cambiar. + El tipo de retorno: En un mtodo sobrecargado el tipo de retorno puede cambiar, en un mtodo sobreescrito NO puede cambiar, excepto por subtipos del tipo declarado originalmente. + Excepciones: En un mtodo sobrecargado las excepciones pueden cambiar, en un mtodo sobreescrito pueden reducirse o eliminarse pero NO deben de arrojarse excepciones nuevas o ms amplias. + Acceso: En un mtodo sobrecargado puede cambiar, en un mtodo sobreescrito el acceso NO debe de hacerse ms restrictivo(puede ser menos restrictivo). + Al invocar: En un mtodo sobrecargado los argumentos son los que determinan qu mtodo es el que se invocar, en un mtodo sobreescrito el tipo de objeto determina qu mtodo es elegido.

2.7.-Sobrecarga de operadores: Los operadores de Java son muy parecidos en estilo y funcionamiento a los de C. Tanto C, como C++, como Java, proporcionan un conjunto de operadores para poder realizar acciones sobre uno o dos operandos. Un operador que acta sobre un solo operando es un operador unario, y un operador que acta sobre dos operandos es un operador binario. Algunos operadores pueden funcionar como unarios y como binarios, el ejemplo ms claro es el operador - (signo menos). Como operador binario, el signo menos, el cual hace que el operando de la derecha sea sustraido al operando de la izquierda; como operador unario hace que el signo algebraico del operando que se encuentre a su derecha sea cambiado. En la siguiente tabla aparecen los operadores que se utilizan en Java, por orden de precedencia: . ++ ! * + << < & && ? = op= [] ~ / >> > <= ^ >= == () -instanceof % >>> != | || :

(*=

/=

%=

+= -= etc.) ,

Los operadores numricos se comportan como esperamos: int + int = int Los operadores relacionales devuelven un valor booleano. Para las cadenas, se pueden utilizar los operadores relacionales para comparaciones adems de + y += para la concatenacin: String nombre = "nombre" + "Apellido"; El operador = siempre hace copias de objetos, marcando los antiguos para borrarlos, y ya se encargar el garbage collector de devolver al sistema la memoria ocupada por el objeto eliminado. Java, a diferencia de C++, no soporta la sobrecarga de operadores. Esto significa que no es posible redefinir el entorno en el que acta un operador con respecto a los objetos de un nuevo tipo que el programador haya definido como propios. Un caso interesante, que se sale de la afirmacin anterior, es el operador + (signo ms), que se puede utilizar para realizar una suma aritmtica o para concatenar cadenas (Java lo sobrecarga internamente!). Cuando el signo ms se utiliza en esta ltima forma, el operando

de la derecha se convierte automticamente en una cadena de caracteres antes de ser concatenada con el operando que se encuentra a la izquierda del operador +. Esto asume que el compilador sabe que el operando de la derecha es capaz de soportar la conversin. Y ese conocimiento lo tiene porque comprueba todos los tipos primitivos y muchos de los tipos internos que se utilizan. Obviamente, el compilador no sabe absolutamente nada de los tipos que haya definido el programador. A continuacin se detallan algunos de los operadores que admite Java y que se suelen agrupar en operadores aritmticos, relacionales y condicionales, operadores lgicos y que actan sobre bits y, finalmente, operadores de asignacin. Operadores Aritmticos Java soporta varios operadores aritmticos que actan sobre nmeros enteros y nmeros en coma flotante. Los operadores binarios soportados por Java son: + * / % suma los operandos resta el operando de la derecha al de la izquierda multiplica los operandos divide el operando de la izquierda entre el de la derecha resto de la divisin del operando izquierdo entre el derecho

Como se ha indicado anteriormente, el operador ms (+), se puede utilizar para concatenar cadenas, como se observa en el ejemplo siguiente: "miVariable tiene el valor " + miVariable + " en este programa" Esta operacin hace que se tome la representacin como cadena del valor de miVariable para su uso exclusivo en la expresin. De ninguna forma se altera el valor que contiene la variable. En C++ no se soporta la concatenacin de cadenas con el operador ms (+); hay que utilizar la funcin strcat() para poder concatenar dos cadenas y el uso de esta funcin puede resultar peligroso porque no hay proteccin contra el traspaso de los lmites del array que se utiliza como destino de la cadena concatenada. El operador mdulo (%), que devuelve el resto de una divisin, a diferencia de C++, en Java funciona con tipos en coma flotante adems de con tipos enteros. Cuando se ejecuta el programa que se muestra en el ejemplo java401.java. La salida que se obtiene por pantalla tras la ejecucin del ejemplo es la que se reproduce a continuacin: %java x mod y mod 10 = 3.299999999999997 10 = java401 3

Los operadores unarios que soporta Java son: + ++ -indica un valor positivo negativo, o cambia el signo algebraico suma 1 al operando, como prefijo o sufijo resta 1 al operando, como prefijo o sufijo

En los operadores de incremento (++) y decremento (--), en la versin prefijo, el operando aparece a la derecha del operador, ++x; mientras que en la versin sufijo, el operando aparece a la izquierda del operador, x++. La diferencia entre estas versiones es el momento en el tiempo en que se realiza la operacin representada por el operador si ste y su operando aparecen en una expresin larga. Con la versin prefijo, la variable se incrementa (o decrementa) antes de que sea utilizada para evaluar la expresin en que se encuentre, mientras que en la versin sufijo, se utiliza la variable para realizar la evaluacin de la expresin y luego se incrementa (o decrementa) en una unidad su valor. Operadores Relacionales y Condicionales Aunque Java y C++ soportan los mismos operadores relacionales, devuelven valores diferentes. Los operadores relacionales en Java devuelven un tipo booleano, true o false; mientras que en C++ devuelven un valor entero, en donde se puede considerar al valor cero como false y a un valor no-cero como true. > >= < <= == != el operando izquierdo es mayor que el derecho el operando izquierdo es mayor o igual que el derecho el operando izquierdo es menor que el derecho el operando izquierdo es menor o igual que el derecho el operando izquierdo es igual que el derecho el operando izquierdo es distinto del derecho

Los operadores relacionales combinados con los operadores condicionales (o lgicos en C++), se utilizan para obtener expresiones ms complejas. Los operadores condicionales que soporta Java son: && || ! expresiones izquierda y derecha son true o la expresin izquierda o al expresin de la derecha son true la expresin de la derecha es false

Los programadores C++ se encontrarn con que Java restringe el uso de estos operadores, porque en C++ la representacin de true y false es muy diferente a Java. En Java, los operandos de estos operadores deben ser tipos booleanos, o expresiones que devuelvan un tipo booleano, mientras que en C++ puede ser cualquier tipo entero o expresin que devuelva un tipo entero, sin restricciones.

Una caracterstica importante del funcionamiento de los operadores && y ||, tanto en Java como en C++ (y que es pasado a veces por alto, incluso por programadores experimentados) es que las expresiones se evalan de izquierda a derecha y que la evaluacin de la expresin finaliza tan pronto como se pueda determinar el valor de la expresin. Por ejemplo, en la expresin siguiente: ( a < b ) || ( c < d ) si la variable a es menor que la variable b, no hay necesidad de evaluar el operando izquierdo del operador || para determinar el valor de la expresin entera. En casos de complejas y largas expresiones, el orden en que se realizan estas comprobaciones puede ser fundamental, y cualquier error en la colocacin de los operandos puede dar al traste con la evaluacin que se desea realizar y, estos errores son harto difciles de detectar, ya que se debe estudiar concienzudamente el resultado de las expresiones en tiempo de ejecucin para poder detectar el problema. Operadores a Nivel de Bits Java y C, C++ comparten un conjunto de operadores que realizan operaciones sobre un solo bit cada vez. Java tambin soporta el operador >>>, que no existe en C o C++ y, adems, el entorno en el que se realizan algunas de las operaciones no siempre es el mismo en Java que en los otros lenguajes. Los operadores de bits que soporta Java son los que aparecen en la siguiente tablita: Operador >> << >>> & | ^ ~ Uso Operando >> Despl Operando << Despl Operando >>> Despl Operando & Operando Operando | Operando Operando ^ Operando ~Operando Operacin Desplaza bits del operando hacia la derecha las posiciones indicadas (con signo) Desplaza bits del operando hacia la izquierda las posiciones indicadas Desplaza bits del operando hacia la derecha las posiciones indicadas (sin signo) Realiza una operacin AND lgiga entre los dos operandos Realiza una operacin OR lgica entre los dos operandos Realiza una operacin lgica OR Exclusiva entre los dos operandos Complementario del operando (unario)

En Java, el operador de desplazamiento hacia la derecha sin signo, rellena los bits que pueden quedar vacos con ceros. Los bits que son desplazados fuera del entorno se pierden. En el desplazamiento a la izquierda, hay que ser precavidos cuando se trata de desplazar enteros positivos pequeos, porque el desplazamiento a la izquierda tiene el efecto de multiplicar por 2 para cada posicin de bit que se desplace; y esto es peligroso porque si se

desplaza un bit 1 a la posicin ms alta, el bit 31 o el 63, el valor se convertir en negativo. Operadores de Asignacin El operador = es un operador binario de asignacin de valores. El valor almacenado en la memoria y representado por el operando situado a la derecha del operador es copiado en la memoria indicada por el operando de la izquierda. Al contrario que en C++, el operador de asignacin (ni ningn otro) no se puede sobrecargar en Java. Java soporta toda la panoplia de operadores de asignacin que se componen con otros operadores para realizar la operacin que indique ese operador y luego asignar el valor obtenido al operando situado a la izquierda del operador de asignacin. De este modo se pueden realizar dos operaciones con un solo operador. += -= >>= >>>= *= /= %= &= |= ^= <<=

Por ejemplo, las dos sentencias que siguen realizan la misma funcin: x x = x + y; += y;

Y las otras comprobaciones siguen el mismo patrn. C++ no soporta el operador >>>= porque tampoco soporta el operador a nivel de bits de desplazamiento sin signo (>>>). Operadores Ternario if-then-else Java, lo mismo que C y C++, soporta este operador ternario. No obstante, la construccin utilizada por este operador es lago confusa, aunque se puede llegar a entender perfectamente cuando uno lee en el pensamiento lo que est escrito en el cdigo. La forma general del operador es: expresion ? sentencia1 : sentencia2 en donde expresion puede ser cualquier expresin de la que se obtenga como resultado un valor booleano, porque en Java todas las expresiones condicionales se evalan a booleano; y si es true entonces se ejecuta la sentencia1 y en caso contrario se ejecuta la sentencia2. La limitacin que impone el operador es que sentencia1 y sentencia2 deben devolver el mismo tipo, y ste no puede ser void. Puede resultar til para evaluar algn valor que seleccione una expresin a utilizar, como en la siguiente sentencia: cociente = denominador == 0 ? 0 : numerador / denominador Cuando Java evala la asignacin, primero mira la expresin que est a la izquierda del interrogante. Si denominador es cero, entonces evala la expresin que est entre el interrogante y los dos puntos, y se utiliza como valor de la expresin completa. Si

denominador no es cero, entonces evala la expresin que est despus de los dos puntos y se utiliza el resultado como valor de la expresin completa, que se asigna a la variable que est a la izquierda del operador de asignacin, cociente. En el ejemplo java402.java se utiliza este operador para comprobar que el denominador no es cero antes de evaluar la expresin que divide por l, devolviendo un cero en caso contrario. Hay dos expresiones, una que tiene un denominador cero y otra que no. class public int int int int // // // int int // static void a b c d java402 main( String = = = = args[] ) { { 28; 4; 45; 0;

Utilizamos el operador ternario para asignar valores a las dos variables e y f, que son resultado de la evaluacin realizada por el operador e = (b == 0) ? 0 : (a / b); f = (d == 0) ? 0 : (c / d); int f = c / d; "a "b "c "d "a "c / / = = = = b d " " " " = = " " + + + + + + a b c d e f ); ); ); ); ); );

System.out.println( System.out.println( System.out.println( System.out.println( System.out.println(); System.out.println( System.out.println( } }

El programa se ejecuta sin errores, y la salida que genera por pantalla es la que se reproduce: %java a b c d a c/d=0 / = = = = b = java402 28 4 45 0 7

Si ahora cambiamos la lnea que asigna un valor a la variable f, y quitamos este operador, dejndola como: int f = c / d; se producir una excepcin en tiempo de ejecucin de divisin por cero, detenindose la

ejecucin del programa en esa lnea. %java java.lang.ArithmeticException: / by zero at java402.main(java402.java:40) Errores comunes en el uso de Operadores Uno de los errores ms comunes que se cometen cuando se utilizan operadores es el uso incorrecto, o no uso, de los parntesis cuando la expresin que se va a evaluar es compleja. Y esto sigue siendo cierto en Java. Cuando se programa en C/C++, el error ms comn es el siguiente: while( // } x . = y . ) { . java402

EL programador intenta realmente hacer una equivalencia (==) en vez de una asignacin. En C/C++ el resultado de esta asignacin siempre ser true si y no es cero, y lo ms seguro es que esto se convierta en un bucle infinito. En Java, el resultado de esta expresin no es un booleano, y el compilador espera un booleano, que no puede conseguir a partir de un entero, as que aparecer un error en tiempo de compilacin que evitar que el programa se caiga al ejecutarlo. Es decir, este error tan comn, para que se d en Java tienen que ser x e y booleanos, lo cual no es lo ms usual. Otro error muy difcil de detectar en C++ es cuando se utiliza el operador unario & cuando la lgica requiere un operador &&; o utilizar el operador unario |, en lugar del operador ||. Este es otro problema difcil de detectar porque el resultado es casi siempre el mismo, aunque slo por accidente. En Java, no ocurre esto y se puede utilizar perfectamente el operador unario & como sinnimo del operador &&, o el operador | como sinnimo de ||; pero si se hace as, la evaluacin de la expresin no concluir hasta que todos los operandos hayan sido evaluados, perdiendo de esta forma las posibles ventajas que podra reportar la evaluacin de izquierda a derecha. Moldeo de Operadores Es lo que se conoce como casting, refirindose a "colocar un molde". Java automticamente cambia el tipo de un dato a otro cuando es pertinente. Por ejemplo, si se asigna un valor entero a una variable declarada como flotante, el compilador convierte automticamente el int a float. El casting, o moldeo, permite hacer esto explcitamente, o forzarlo cuando normalmente no se hara. Para realizar un moldeo, se coloca el tipo de dato que se desea (incluyendo todos los modificadores) dentro de parntesis a la izquierda del valor. Por ejemplo: void int long long i l l2 moldeos() = = = { 100; (long)i; (long)200;

} Como se puede ver, es posible realizar el moldeo de un valor numrico del mismo modo que el de una variable. No obstante, en el ejemplo el moldeo es superfluo porque el compilador ya promociona los enteros a flotantes cuando es necesario automticamente, sin necesidad de que se le indique. Aunque hay otras ocasiones en que es imprescindible colocar el moldeo para que el cdigo compile. En C/C++ el moldeo puede causar autnticos quebraderos de cabeza. En Java, el moldeo es seguro, con la excepcin de cuando se realiza una conversin estrecha, es decir, cuando se quiere pasar de un dato que contiene mucha informacin a otro que no puede contener tanta, en donde se corre el riesgo de perder informacin. Aqu es donde el compilador fuerza a que se coloque un moldeo expreso, indicando al programador que "esto puede ser algo peligroso, as que si quieres que lo haga, dmelo expresamente". Cuando se trata de una conversin ancha, no es necesario el moldeo explcito, ya que el nuevo tipo podr contener ms informacin que la que contiene el tipo original, no ocasionndose ninguna prdida de informacin, as que el compilador puede realizar el moldeo explcitamente, sin la intervencin del programador para confirmar la accin. Java permite el moldeo de cualquier tipo primitivo en otro tipo primitivo, excepto en el caso de los booleanos, en que no se permite moldeo alguno. Tampoco se permite el moldeo de clases. Para convertir una clase en otra hay que utilizar mtodos especficos. La clase String es un caso especial que se ver ms adelante.

Por qu java no soporta la sobre carga de operadores? java no soporta sobrecarga de operadores , aunque el sistema internamente la utiliza, pero est ocultada al programador, por ejemplo si te fijas al hacer un Int ejemplo=2+1; En java eso es valido y le asigna un 3 a la variable ejemplo la funcionalidad fue sumar, sin embargo en este: String ejemplo="hola"+"mundo"; El operador + se utiliza con otra finalidad : Concatenar , lo ves? Java si usa la sobrecarga de operadores, pero esta oculta para el programador, sea no te permite usarla. Porque? Bsicamente para no llevar a confusin , imagina que defines una clase llamada "sobreEscribe" en la cual sobrecargaras el operador suma y le asinaras tu propia forma de trabajar por ejemplo sumar fracciones y mas tarde defines la clase "fracciones" heredando la clase "sobreEscribe" el resultado seria que en la clase "fracciones" el operador suma cambiara su comportamiento. Si llegase ahora un porgramador externo y revisara la clase fracciones podria confundirse y creer que este operador mantiene el comportamiento normal , para saber que tiene el comportamiento actual tendria que ir a revisar "sobreEscribe", ahora imagina que esta herencia se realiza entre varias clases , seria muy dificil saber si realmente se esta cambiando el comportamiento del operador suma o no. Esta es una de las razones mas fuertes por las cuales Java no soporta la sobrecarga de operadores basicamente para no llevar a confusion y al fin y al cabo no es necesaria , puedes utilizar tus propios metodos

Qu es la sobrecarga de operadores? En C++ se pueden hacer operaciones con los tipos bsicos del lenguaje: se pueden sumar enteros, compararlos, etc. Lo siguiente es perfectamente vlido en C++ int int int c = a + b; Si estos tipos no son los bsicos del lenguaje, no se puede hacer sumas con ellos. Por ejemplo, si ClaseC es una clase que tengo definida en C++, el siguiente cdigo dar error. ClaseC ClaseC ClaseC c = a + b; C++ permite que hagamos estas cosas si definimos en algn sitio cmo se suman esas clases. Definiendo cmo se hacen las operaciones, podremos escribir las operaciones con nuestras clases de la misma forma que si se trataran de tipos bsicos del lenguaje. De hecho podemos definir cualquier operador que nos d C++, desde algunos muy normales como suma, resta, multiplicacin, mayor qu, etc, a otros un poco ms raros como el operador () o el [], de forma que ClaseC[i] o ClaseC(i,j) pueden devolver lo que nosostros queramos. Sobrecarga del operador suma Si tenemos una clase ComplejoC que representa un complejo, para poder sumar dos de estas clases simplemente poniendo un +, como con cualquier tipo bsico de C++, debemos sobrecargar el operador +, darle una nueva funcionalidad. La sobrecarga de un operador suma se hace de la siguiente manera a; b; c; a=3; b=4; c;

class {

ComplejoC public: // Permite sumar un ComplejoC + con un double ComplejoC operator sumar operator sumar (double con double sumando); un array

//

Permite ComplejoC //

un ComplejoC + (const dos (const

sumando[]); entre s.

Permite

ComplejoC ComplejoC

ComplejoC };

operator +

&sumando);

Aqu estamos redefiniendo tres operadores suma para que nos permita sumar a nuestra clase ComplejoC cosas como un double, un array de double (que supondremos contiene dos double, aunque no tenemos forma de comprobarlo) y otra clase ComplejoC . En estas funciones hemos puesto const en los parmetros para no poder cambiarlos dentro del cdigo. En la tercera funcin pasamos ComplejoC por referencia (el &), para evitar que se hagan copias innecesarias. En la primera funcin no es necesario nada de esto, puesto que es un simple double. En la segunda, ponemos const para no poder modificar el array, pero no es necesaria la referencia, puesto que los arrays son punteros. A la hora de implementar debemos tener cuidado con los const que hemos puesto. Por ejemplo, en el tercer operador +, recibimos un sumando que es const. El cdigo que implementemos dentro no puede modificar dicho sumando, ni puede llamar a ningn mtodo de ese sumando que no est declarado como const. Si lo intentamos, el compilador dar error. Supongamos que ComplejoC tiene un atributo double x (parte real) y un mtodo dameX() para obtener dicho atributo, este mtodo debe estar declarado const para poder llamarlo desde nuestro operator +. Ms o menos esto: class { public: // Atencin al const del final. Sin el no podemos llamar a sumando.dameX(). ComplejoC

double };

dameX()

const;

de forma que en el operator + podemos llamar a sumando.dameX(). Una vez implementados estos mtodos, podemos hacer operaciones como ComplejoC ComplejoC // b // double b // b = a + b; Cuando el compilador lee a + 1.0, lo interpreta como a.operator + (1.0), es decir, la llamada al operador suma al que se le pasa como parmetro un double . De la misma forma sucede con los otros dos operadores suma. Sin embargo, esto nos da un pequeo problema. Qu pasa si ponemos 1.0 + a?. Debera ser lo mismo, pero al compilador le da un pequeo problema. Intenta llamar al mtodo operator + de 1.0, que no existe, puesto que 1.0 ni es una clase ni tiene mtodos. Para solucionar este problema tenemos la sobrecarga de operadores globales. Sobrecarga de operadores suma globales Un operador global es una funcin global que no pertenece a ninguna clase y que nos indica cmo operar con uno o dos parmetros (depende del tipo de operador). En nuestro ejemplo de las sumas, para poder poner los sumandos al revs, deberamos definir las siguientes funciones globales: = Aprovechando Aprovechando = Aprovechando c[] a la la a la = primera + segunda {1.0, + tercera a; b; sobrecarga 1.0; sobrecarga 2.0}; c; sobrecarga

ComplejoC operator + (double sumando1, const ComplejoC &sumando2); ComplejoC operator + (double sumando1[], const ComplejoC &sumando2); Estas funciones le indican al compilador cmo debe sumar los dos parmetros y qu devuelve. Con ellas definidas e implementadas, ya podemos hacer b // b = c + a; Esta sobrecarga es especialmente til cuando tratamos con una clase ya hecha y que no podemos modificar. Por ejemplo, cout es de la clase ostream y no podemos modificarla, sin embargo nos sera de utilidad sobrecargar el operador << de ostream de forma que pueda escribir nuestros nmeros complejos. La siguiente llamada nos dar error mientras no redefinamos el operator << de ostream . cout << a << endl; // a es un ComplejoC c = era un 1.0 array + de a; double

Con la sobrecarga de operadores globales podemos definir la funcin ostream &operator << (ostream &salida, const ComplejoC &valor); Con esta funcin definida, el complejo se escribir en pantalla como indique dicha funcin. Esta funcin deber escribir la parte real e imaginaria del complejo en algn formato, utilizando algo como salida << valor.dameX() << " + " << valor.dameY() << "j"; El operador devuelve un ostream, que ser un return cout. De esta forma se pueden encadenar las llamadas a cout de la forma habitual. cout << a << " + " << b << endl; Primero se evala operator << (cout, a), que escribe a en pantalla y devuelve un cout, con lo que la expresin anterior quedara, despus de evaluar esto

cout << " + " << b << endl; y as consecutivamente. Hay que tener en cuenta que estos operadores globales no son de la clase, as que slo pueden acceder a mtodos y atributos pblicos de la misma. El operador cast Un operador interesante es el operador "cast". En C++, si tenemos dos tipos bsicos distintos, podemos pasar de uno a otro haciendo un cast (siempre que sean compatibles de alguna forma). Por ejemplo int double b; a = (int)b; El cast consiste en poner delante, entre parntesis, el tipo que queramos que sea. En algunos casos, como en el de este ejemplo, el cast se hace automticamente y no es necesario ponerlo. Puede que de un "warning" en el compilador avisando de que perderemos los decimales. En principio, con las clases no se puede hacer cast a otros tipos, pero es posible declarar operadores que lo hagan. La sintaxis sera: class { public: // } Con este podemos hacer cast de nuestra clase a un double . Es nuestro problema decidir cmo se hace ese cast. En el cdigo de ejemplo que hay ms abajo se ha definido como la operacin mdulo del nmero complejo. double ComplejoC a; b; Permite hacer un cast de ComplejoC a double (); operator double ComplejoC a;

a = (double)b; En el operator cast se pone operator seguido del tipo al que se quiere hacer el cast. No se pone el tipo del valor devuelto, puesto que ya est claro. Si ponemos operator double, hay que devolver un double . En el operator cast no se pone parmetro, puesto que el parmetro recibido ser una instancia de la clase. Conviene tener cuidado con definir muchos operadores cast, puesto que el compilador los tendr todos presentes y ser capaz, encadenando unos con otros, de hacer cast entre tipos que no tienen nada que ver. Por ejemplo, si sumamos un ComplejoC con un DibujoC (que no tienen nada que ver) y ambos tienen cast e int, es posible que el compilador los transforme ambos en int y luego los sume como enteros. Cmo hacemos un cast al revs?. Es decir, Cmo podemos convertir un double a ComplejoC?. El asunto es sencillo, basta hacer un constructor que admite un double como parmetro. class { public: ComplejoC }; Este constructor sirve para lo que ya sabemos ComplejoC a(3.0); o podemos usarlo para hacer un cast de double a ComplejoC ComplejoC a = (ComplejoC)3.0; a; (double valor); ComplejoC

El operador igual El operator = es como los dems. Simplemente un pequeo detalle. C++ por defecto tiene el operador igual definido para clases del mismo tipo. Por ejemplo, sin necesidad de redefinir nada, podemos hacer ComplejoC ComplejoC a = b; Este igual por defecto lo nico que hace es copiar el contenido del uno sobre el otro, como si fueran bytes, sin saber qu atributos est copiando ni qu significan. Para clases sencillas, que solo tienen atributos que no son punteros, esto es ms que suficiente. Si embargo, si algn atributo es un puntero, tenemos que tener mucho cuidado con lo que hacemos. Supongamos que ClaseC tiene un atributo Atributo que es un puntero. Supongamos tambin que en el constructor de la clase, se hace new del puntero para que tenga algo y en el destructor se hace el delete correspondiente. ClaseC { public: // Se crea Atributo un array = de () new tres enteros { int[3]; } // Se ~ClaseC delete [] libera el () array. { Atributo; } protected: int }; *Atributo; ClaseC a; b;

Si ahora hacemos esto // a tiene ahora un array de 3 enteros en su interior ClaseC *a = new ClaseC();

// b tiena ahora otro array de 3 enteros en su interior ClaseC *b = new ClaseC();

/* Se copia el Atributo de b sobre el de a, es decir, ahora a->Atributo apunta *a // delete b; Cuando hacemos a=b, con el operador igual por defecto de C++, se hace que el puntero Atributo de a apunte al mismo sitio que el de b. El array original de a->Atributo lo hemos perdido, sigue ocupando memoria y no tenemos ningn puntero a l para liberarlo. Cuando hacemos delete b, el destructor de b se encarga de liberar su array. Sin embargo, al puntero a->Atributo nadie le avisa de esta liberacin, se queda apuntando a una zona de memoria que ya no es vlida. Cuando intentemos usar a->Atributo ms adelante, puede pasar cualquier cosa (cambios aleatorios de variables, caidas del programa, etc). En el tema de punteros tienes un poco ms detallado todo esto. All se habla de estructuras, pero tambin se aplica a clases. La forma de solucionar esto, es definiendo nosotros un operator = que haga una copia real del array, liberando previamente el nuestro o copiando encima los datos. ClaseC { public: ClaseC &operator = (const int ClaseC &original) { i; /* Damos por supuesto que ambos arrays existen y son de Ahora si al mismo sitio = que la hemos que b->Atributo */ *b; liado.

tamao for Atributo[i] }; Sobrecarga del operador new y delete

3 =

*/ (i=0;i<3;i++) original.Atributo[i]; }

Otro operador interesante de sobrecargar es el new y el delete. Si los sobrecargamos dentro de la clase, cada vez que hagamos un new a nuestra clase se llamar a nuestro operador. Ms interesante es la sobrecarga de los operadores new y delete globales. Sobrecargando estos operadores se llamar a nuestras funciones cada vez que hagamos un new o un delete de cualquier cosa (clases o variables). Esta caracterstica nos permite hacer contabilidad de punteros, para ver si liberamos todo lo que reservamos o liberamos lo mismo ms veces de la cuenta.

http://ocw.upm.es/lenguajes-y-sistemas-informaticos/programacion-en-javai/Contenidos/LecturaObligatoria/14-tiposdemetodos.pdf http://zarza.usal.es/~fgarcia/doc/tuto2/II_5.htm

También podría gustarte