Você está na página 1de 39

Versión Octubre de 2001

SECCION 1
Declaración y control de Acceso..................................2
Objetivo 1............................................................................................................................2
Arrays..............................................................................................................................2
Declaración sin asignación..............................................................................................2
Creación y Declaración Simultanea................................................................................3
Arrays Java VS Arrays C/C++ .......................................................................................3
Los arrays conocen su tamaño........................................................................................4
Arrays Java VS Arrays VB.............................................................................................4
Combinar declaración con inicialización........................................................................5
Objetivo 2............................................................................................................................9
Comparando las clases de C++/VB con las de Java.......................................................9
El rol de las clases en Java..............................................................................................9
La clase mas sencilla.....................................................................................................10
Creando una clase sencilla- HelloWorld.......................................................................10
La magia del nombre main............................................................................................10
Creando una instancia de una Clase..............................................................................11
Creando Métodos..........................................................................................................12
Variables Automáticas...................................................................................................13
Modificadores y Encapsulamiento................................................................................14
Usando modificadores en combinación........................................................................19
Objetivo 3..........................................................................................................................28
Nota de este objetivo.....................................................................................................28
¿Qué es un constructor?................................................................................................28
¿Cuándo proporciona Java el constructor predefinido?................................................28
El prototipo del constructor predefinido.......................................................................30
Objetivo 4..........................................................................................................................36
Nota de este objetivo.....................................................................................................36
Métodos en la misma clase...........................................................................................36
Métodos en una subclase...............................................................................................37
1. Declaración y control de Acceso
Objetivo 1.
Escribir código que declare, construya e inicie arrays de cualquier tipo base, usando
cualquiera de las formas permitidas, ambas para declaración y para inicialización.

Arrays.
Los arrays en Java son similares en sintaxis a los arrays en otros lenguajes como C/C++ y
Visual Basic. Sin embargo, Java elimina la característica de C/C++ mediante la cual puedes
pasar los corchetes ([]) accediendo a los elementos y obteniendo sus valores utilizado
punteros. Esta capacidad en C/C++, aunque poderosa, propicia la escritura de software
defectuoso. Aunque Java no soporta esta manipulación directa de punteros, esta fuente de
errores es removida.

Un array es un tipo de objeto que contiene valores llamados elementos. Esto te da un


conveniente contenedor de almacenamiento para un grupo de valores que pueden ser
modificados durante el programa, y permite que accedas y cambies los valores según lo
necesites. A diferencia de las variables que son accedidas por un nombre, los elementos de
un array son accedidos por números comenzando por cero. De esta manera puedes
“avanzar” a través del array, accediendo a cada elemento en turno.

Todos los elementos de un array deben ser del mimo tipo. El tipo de elementos de un
array, se decide cuando el array se declara.

Si lo que necesitas es una manera para almacenar un grupo de elementos de tipos


diferentes, puedes usar las clases de colecciones, estas son una nueva característica en Java
2 y son discutidas en la sección 10.

Declaración sin asignación.


La declaración de un array no asigna almacenamiento alguno, esta solo anuncia la
intención de crear un array. Una diferencia significativa con la manera en que C/C++
declara un array es que el tamaño no se especifica con el identificador. Por lo tanto lo
siguiente causara un error durante la compilación

int num[5];

El tamaño de un array se da cuando este es realmente creado con el operador new:

int num[];
num = new int[5];
Creación y Declaración Simultanea.
Lo anterior puede ser compactado en una sola línea así:

int num[] = new int[5];

También los corchetes pueden ser además colocados después del tipo de dato o después
del nombre del array. Por lo tanto son legales las siguientes declaraciones:

int[] num;
int num[];

Puedes leer esto de la siguiente manera:

• Un array de enteros llamado num


• Un array llamado num de tipo entero.

Arrays Java VS Arrays C/C++ .

Una gran diferencia entre java y C/C++ es que en java, se conocen de que tamaño
son los arrays, y el lenguaje proporciona protección para no sobrepasar los limites
del array.

Este consejo es particularmente útil si vienes de un ambiente de programación como Visual


Basic y no es muy común iniciar el conteo de un array desde 0. También ayuda a evitar uno
de los mas insidiosos errores de C/C++.

Por lo tanto, lo siguiente causará el siguiente error en tiempo de ejecución:


ArrayIndexOutOfBoundException

int[] num = new int [5];


for (int i = 0;i<6;i++){
num[i] = i*2;
}

Para recorrer un array, la manera mas común es a través del campo length de los arrays,
por lo tanto:

int [] num = new int[5];


for(int i = 0;i<num.length;i++){
num[i]=i*2;
}
Los arrays conocen su tamaño.
Solo en caso de que saltaste la comparación con C/C++ -hecha anteriormente- los arrays en
Java siempre conocen cual es su tamaño, y este es representado en el campo length. Así,
puedes llenar dinámicamente un array con el código siguiente:

int myarray[] = new int [10];


for(int j=0; j<myarray.length; j++){
myarray[j]=j;
}

Nota que los arrays tienen el campo length y no el método length(). Cuando comiences a
utilizar Strings usaras el método length, de la siguiente manera:
s.length();

En un array length es un campo (o propiedad) no un método.

Arrays Java VS Arrays VB


Los arrays en Java siempre comienzan desde cero. Los arrays en VB pueden comenzar
desde 1 si la declaración Option base se usa. En Java no hay equivalente para el comando
redim preserve a través del cual puedes cambiar el tamaño de un array sin borrar su
contenido. Pero por supuesto puedes crear un nuevo array con un nuevo tamaño y copiar
los elementos actuales en ese array y obtener el mismo resultado.

La declaración de un array puede tener múltiples conjuntos de corchetes (“[]”). Java


formalmente no soporta los arrays multidimensionales; sin embargo si soporta arrays de
arrays; también conocidos como arrays anidados.

Una diferencia importante entre los arrays multidimensionales, como en C/C++ y los
arrays anidados, es que cada array no tiene que ser del mismo tamaño. Si vemos un array
como una matriz, la matriz no tiene que ser una matriz rectángulo .
De acuerdo con la Especificación del Lenguaje Java:

(http://java.sun.com/docs/books/jls/html/10.doc.html#27805)

“El número de corchetes indica la profundidad de un array anidado”

En otros lenguajes esto se conoce como la dimensión de un array. Así podrías colocar los
corchetes en un mapa con un array de 2 dimensiones:

int [][];

la 1ª dimensión podría ser la coordenada X y la segunda la coordenada Y.

_
NT.: En otras palabras; cada array puede tener un tamaño distinto.
Combinar declaración con inicialización.
En vez de ciclarse a través de un array para llevar a cabo la inicialización, un array puede
ser creado e inicializado a la vez en una sola declaración.

Esto es recomendable particularmente para arrays pequeños. La siguiente línea creara un


array de enteros y lo llenara con los números 0 hasta el 4.

int k[] = new int[] {0,1,2,3,4};

Nota que en ninguna parte necesitas especificar el número de elementos en el array. Puedes
analizar esto, preguntándote si el siguiente código es correcto:

Int k = new int[5]{0,1,2,3,4}; //¡¡¡ error, no compilara !!!

Puedes llenar y crear arrays simultáneamente con cualquier tipo de dato, por lo tanto
puedes crear un array de cadenas, de la siguiente manera:

String s[] = new String [] {“Zero”,”One”,”Two”,”Three”,”Four”};

Los elementos de un array pueden ser direccionados como lo harías en C/C++:

String s[] = new String [] {“Zero”,”One”,”Two”,”Three”,”Four”};


System.out.println(s[0]);

Esto mostrará la cadena Zero.

Ejercicio 1)
Cree una clase con un método que simultáneamente cree e inicialize un array de cadenas.
Inicializa el array con cuatro nombres, después muestra el primer nombre del array.
Ejercicio 2)
Crea una clase que cree un array de cadenas de 5 elementos llamado Fruit en el nivel de
clase, pero no lo inicializes con cualquier valor. Crea un método llamado amethod. En
amethod inicializa los primeros cuatro elementos con nombres de frutas. Crea otro método
llamado modify y cambia el contenido del primer elemento del array Fruit para que
contenga la cadena “bicycle”. Dentro del método modify crea un ciclo for que imprima
todos los elementos del array

Solución sugerida para el ejercicio 1.

public class Bevere{


public static void main(String argv[]){
Bevere b = new Bevere();
b.Claines();
}
public void Claines(){
String[] names= new String[]{"Peter","John","Balhar","Raj"};
System.out.println(names[0]);
}
}

Nota: La sintaxis para la creación e inicialización simultanea no es evidente y vale la pena


practicarla. Se preguntó por el primer nombre del array para ser mostrado para asegurar
que no utilizarás names[1].

Solución Sugerida para el ejercicio 2.

public class Barbourne{


String Fruit[]= new String[5];
public static void main(String argv[]){
Barbourne b = new Barbourne();
b.amethod();
b.modify();
}
public void amethod(){
Fruit[0]="Apple";
Fruit[1]="Orange";
Fruit[2]="Bannana";
Fruit[3]="Mango";
}
public void modify(){
Fruit[0]="Bicycle";
for(int i=0; i< Fruit.length; i++){
System.out.println(Fruit[i]);
}

}
}

Nota: Cuando el ciclo ejecute la salida de elemento final este será null.

Preguntas.

Pregunta 1)
¿Cómo puedes redimensionar un array en una declaración sencilla manteniendo el
contenido original?
Pregunta 2)
Quieres averiguar el valor del último elemento de un array. Escribiendo el siguiente
Código.¿Qué pasara cuando lo compiles y ejecutes?

public class MyAr{


public static void main(String argv[]){
int[] i = new int[5];
System.out.println(i[5]);
}
}

Pregunta 3)
Quieres hacer un ciclo a través de un array y detenerte cuando llegues al ultimo elemento.
Siendo un buen programador en Java, y olvidando lo que alguna vez conociste acerca de
C/C++, sabes que los arrays contienen información acerca de su tamaño. ¿Cuál de las
siguientes sentencias puedes usar?

1)myarray.length();
2)myarray.length;
3)myarray.size
4)myarray.size();

Pregunta 4)
Tu jefe esta complacido por que escribiste el programa Hello World y te ha dado un
aumento. Ahora te encomienda que crees un juego como el TicTacToe(o puntos y cruces
como lo conocí en mi adolescencia). Decides que para eso necesitas un array
multidimensional. ¿Cuál de las siguientes líneas realizan el trabajo?

1) int i=new int[3][3];


2) int[] i=new int[3][3];
3) int[][] i=new int[3][3];
4) int i[3][3]=new int[][];

Pregunta 5)
Quieres encontrar una manera más elegante para llenar un array que a través de un ciclo
con la sentencia for. ¿Cuál de las siguientes líneas usarías?

1)
myArray{
[1]="One";
[2]="Two";
[3]="Three";
end with

2)String s[5]=new String[] {"Zero","One","Two","Three","Four"};


3)String s[]=new String[] {"Zero","One","Two","Three","Four"};

4)String s[]=new String[]={"Zero","One","Two","Three","Four"};

Respuestas

Respuesta 1)
No puedes redimensionar un array. Necesitas crear un nuevo array temporal con un
tamaño diferente y llenarlo con el contenido del array original. Java Proporciona
contenedores redimencionables con clases como Vector o uno de los miembros de la clase
collection .

Respuesta 2)
Intentar avanzar mas allá del final del array genera un error en tiempo de ejecución. Por
que los arrays son indexados desde 0, el elemento final será i[4] y no i[5].

Respuesta 3)
2) myarray.length;

Respuesta 4)
3) int[][] = new int[3][3];

Respuesta 5)
3) String s[] = new String[]{“Zero,”One”,”Two”,”Three”,”Four”};
Otras Fuentes de este tema:
Este tema es cubierto en el Tutorial de Sun en:
http://java.sun.com/docs/books/tutorial/java/data/arraysAndStrings.html
Richard Baldwin trata este tema en:
http://www.Geocities.com/Athens/Acropolis/3797/Java028.htm
Jyothi Krishnan en:
http://www.geocities.com/SiliconValley/Network/3693/obj_sec1.html#obj1

Bruce Eckel Thinking In Java


Capítulo 8

Objetivo 2.
Declarar clases, clases internas, métodos, variables de instancia estáticas, variables y
variables automáticas(métodos locales), haciendo un uso apropiado de todos los
modificadores permitidos (como son: public, final, static, abstract, y demás). Conocer
importancia de cada uno de estos modificadores ya sea solos o en combinación

Comentario sobre este objetivo


Encuentro un poco molesto que en el objetivo se use la frase “y demás”.
Supongo que esto significa que debes estar conciente de los modificadores:

  native
  transient
  synchronized
  volatile

Comparando las clases de C++/VB con las de Java.


Debido a que Java fue diseñado para facilitar que programadores C++ lo aprendieran, este
tiene muchas similitudes en la manera en que ambos lenguajes “trabajan ” con las clases.
Ambos lenguajes tienen herencia, polimorfismo, y ocultamiento de datos usando
modificadores de visibilidad. Algunas de sus diferencias fueron hechas para hacer de Java
un lenguaje mas fácil de aprender y usar.

El lenguaje C++ implementa la herencia múltiple y así una clase puede tener más de un
padre (o clase) base. Java únicamente permite la herencia simple, es decir, las clases
pueden tener únicamente un padre. Para sobreponer esta limitación, Java tiene una
característica llamada: Interfaces, a la cual los diseñadores de lenguajes le decidieron dar
algunas de las ventajas de la herencia múltiple, pero sin las desventajas. Todas las clases en
Java son descendientes de una gran clase antecesora llamada Object.

El rol de las clases en Java


Las clases son el corazón de Java, todo el código en Java ocurre dentro de una clase. No
hay un concepto de código llano y de posición libre. Hasta la mas sencilla aplicación
HelloWorld involucra la creación de una clase. Para indicar que una clase desciende de otra
case se usa la palabra clave extends. Si extends no se usa, la clase descenderá de la clase
Object lo cual proporciona a la clase creada, algunas funciones básicas incluyendo la
habilidad para mostrar su nombre y algunas de las capacidades requeridas en los Threads.

La clase mas sencilla.


Los requerimientos minimos para definir una clase son: la palabra clave class, el nombre de
la clase y las llaves de apertura y cerradura. Entonces:

class classname {}

es la definición sintacticamente correcta de una clase, pero no es una clase particularmente


útil (sorprendentemente, me he encontrado definiendo clases como esta, cuando creo
ejemplos para ilustrar la herencia)

f
NT: El termino original es keyword.
Normalmente una clase también incluirá un especificador de acceso antes de la palabra
clave class y por supuesto, el cuerpo de la clase entre las llaves. Así, lo siguiente es una
plantilla mas sensata para definir una clase:

public class classmane{


// el cuerpo de la clase va aca
}

Creando una clase sencilla- HelloWorld


Este es un sencillo programa HelloWorld que mostrar la cadena “hello world” en la
pantalla.

public class HelloWorld{


public static void main(String argv[]){
System.out.println("hello world");
}
}//Fin de la Definición de la clase

La palabra clave public es un modificador de visibilidad que indica que la clase deberá ser
visible para cualquier otra clase. Solo una clase por archivo puede ser declarada publica. Si
declaras mas de una clase en un archivo como publica, ocurrirá un error en tiempo de
ejecución. Nota que Java es sensible a mayúsculas en todos los aspectos. El archivo que
contenga esta clase deberá llamarse HelloWorld.java

La palabra clave class indica que una clase comienza a ser definida y HelloWorld es el
nombre de la clase. Nota que la llave de cierre que finaliza la definición de la clase no
involucra un punto y coma de cerradura. El comentario:

//Fin de la Definición de la clase

usa el estilo de comentario de una sola línea que esta disponible en C/C++. Java también
comprende los comentarios multilíneas de la forma /* */.

La magia del nombre main


Dando a un método la siguiente forma, esté obtiene cierta significancia (o magia) cuando
indica a Java que es aquí en donde el programa debe empezar a ejecutarse. (similar al main
del lenguaje C).

public static void main(String argv[]){

Esta línea indica que un método llamado main esta definiéndose, y que toma como
parámetros (o argumentos ) a un array de cadenas. Este método es publico, es decir desde
cualquier parte visible para clase. La palabra clave static indica que este método puede
ejecutarse sin crear una instancia de la clase. Si eso no significa nada para ti, no te
preocupes, en su momento los métodos estáticos (static) se cubrirán con detalle en otra
parte de este tutorial. La palabra clave void indica el tipo de dato retornado por el método
cuando es llamado. Usar void indica que no será retornado ningún valor.

El parámetro del método main:

String argv[]

Indica que el método toma un array de tipo String. Los corchetes indican –como ya vimos-
un array. Observa que el tipo de dato String comienza con una “S” mayúscula. Esto es
importante ya que Java es totalmente sensible a las mayúsculas. Sin estas exactitudes, la
Maquina virtual de Java (JVM) no reconocerá el método como el lugar en donde se debe
comenzar la ejecución del programa.

Creando una instancia de una Clase


La aplicación HelloWold, como describí anteriormente, es útil para ilustrar la más sencilla
de las aplicaciones que puedes crear. Pero le falta mostrar uno de los elementos más
cruciales al usar las clases, la palabra clave new.
La cual indica la creación de una nueva instancia de la clase. En la aplicación HelloWorld
esto no era necesario ya que el único método que se llamó era System.out.println que es un
método estático y no requiere la creación de una clase que utilice la palabra new. Los
métodos estáticos pueden acceder solo a variables estáticas, de las que sólo una instancia
puede existir por la clase. La aplicación de HelloWorld puede modificarse ligeramente para
ilustrar la creación de un nueva instancia de una clase.

public class HelloWorld2{


public static void main(String argv[]){
HelloWorld2 hw = new HelloWorld2();
hw.amethod();
}

public void amethod(){


System.out.println("Hello world");
}
}

Este código crea una nueva instancia de si mismo en la línea:


HelloWorld2 hw = new HelloWorld2();

Esta sintaxis para crear una nueva instancia de una clase es básica para el uso de clases.
Nota cómo el nombre de la clase aparece dos veces. La primera vez indica el tipo de dato
de la referencia a la clase. Esta necesidad no es la misma que el tipo actual de la clase
puesto que ésta se indica después de usar la palabra clave new. El nombre de esta instancia
de la clase es hw. Éste simplemente es un nombre escogido para una variable. Este es un
nombramiento convencional (es decir, utilizando la convención para escritura de código
Java)ya que una instancia de una clase empieza con una letra minúscula, considerando que
la definición de una clase empieza con una letra mayúscula.

El paréntesis vacío para el nombre de la clase HelloWorld() indica que la clase está
creándose sin algún parámetro en su constructor. Si estuvieras creando una instancia de
una clase que se inicializa con un valor o un array como la clase Label o Button el
paréntesis contendría uno o mas valores de inicialización.

Creando Métodos.
Como ilustro en el último ejemplo HelloWorld2, un método en Java es similar a una
función en C/C++ y a una función o sub función en Visual Basic. El método llamado
amethod en este ejemplo se declara como:

public

que indica que puede accederse desde cualquier parte. Retorna el tipo:

void

indicando que ningún valor será retornado. Y los paréntesis vacíos indican que no toma
ningún parámetro.

El mismo método se podría haber definido de estas maneras alternativas:

private void amethod(String s)


private void amethod(int i, String s)
protected void amethod(int i)

Estos ejemplos ilustran algunas otras firmas típicas de declaración de métodos. El uso del
las palabras clave private y protected se cubrirá en otro apartado.

La diferencia entre los métodos de Java y métodos en lenguajes no Orientados a Objetos


como C es que los métodos pertenecen a una clase. Esto significa que ellos se llaman
usando la anotación del punto que indica la instancia de la clase a la que el código
pertenece (Los métodos estáticos son una excepción a esto pero no te preocupes sobre ellos
por el momento).
Así en HelloWorld2 el método amethod se llamo así:

HelloWorld hw = new HelloWorld();


hw.amethod();

Si se hubieran creado otras instancias de la clase HelloWorld el método podría llamarse


desde cada instancia de la clase. Cada instancia de la clase tendría acceso a sus propias
variables. Así lo siguiente involucraría la llamada a el código del método amethod de las
diferentes instancias de la clase.

HelloWorld hw = new HelloWorld();


HelloWorld hw2 = new HelloWorld();
hw.amethod();
hw2.amethod();

Las dos instancias de la clase hw y hw2 podrían tener acceso a variables diferentes.

Variables Automáticas

Las variables automáticas son las variables de los métodos. Estas entran en el alcance del
programa cuando el código del método empieza a ejecutarse y dejan de existir una vez que
el método deja de ejecutarse. Son sólo visibles dentro del método y son útiles
principalmente para la manipulación datos temporales. Si quieres que un valor permanezca
entre las llamadas de un método entonces la variable necesita ser creada al nivel de la clase.

Una variable automática será la "sombra" de una variable de nivel de clase.

Así el código siguiente mostrará 99 y no 10:

public class Shad{


public int iShad=10;
public static void main(String argv[]){
Shad s = new Shad();
s.amethod();
}//fin de main
public void amethod(){
int iShad=99;
System.out.println(iShad);
}//fin de amethod
}

Modificadores y Encapsulamiento.

Los modificadores de visibilidad son parte del mecanismo de encapsulamiento para


Java. El encapsulamiento permite la separación de la interfase de la
implementación de métodos.
A menudo estos métodos son para recuperar y actualizar los valores de una variable local
privada. Son conocidos como métodos accessor (acceder o obtener el valor de la variable)
y mutator (modificar el contenido de una variable). La convención para nombrar a estos
métodos es setFoo para modificar y getFoo para obtener el contenido de una variable. Así
si estuvieras almacenado una variable llamada age deberías hacerla privada y actualizarla
con :

setAge

y recuperar su valor con:

getAge

Usando código para modificar variables; el valor de la variable también puede verificarse,
por ejemplo: si el valor esta dentro de un rango en particular o revisar si es un numero
positivo.

Private

Las variables privadas son sólo visibles dentro de la misma clase donde se crean. Esto
significa que NO son visibles dentro de las subclases. Esto permite que la variable sea
aislada de ser modificada por cualquier método exceptuando aquellos en la clase actual.
Como se dijo en modificadores y encapsulamiento, esto es útil para separar la interfase de
la implementación.

class Base{
private int iEnc=10;
public void setEnc(int iEncVal){
if(iEncVal < 1000){
iEnc=iEncVal;
}else
System.out.println("Enc value must be less than 1000");
//Or Perhaps thow an exception
}//End if
}
public class Enc{
public static void main(String argv[]){
Base b = new Base();
b.setEnc(1001);
}//End of main
}

Public
El modificador public puede aplicarse a una variable (campo) o una clase. Es
probablemente el primer modificador que conociste aprendiendo Java. Si revisas el código
para HelloWorld.Java, que se programó en un principio, la clase se declaró como:

public class HelloWorld

Esto es porque la JVM para iniciar el método mágico, sólo revisa en una clase declarada
como publica

public static void main(String argv[])

Una clase pública tiene alcance global, y una instancia puede crearse desde cualquier parte
dentro o fuera de un programa. Únicamente una clase en un archivo puede definirse con la
palabra clave public. Si defines más de una clase en un archivo con la palabra clave public
el compilador generará un error

class Base {
public int iNoEnc=77;
}
public class NoEnc{
public static void main(String argv[]){
Base b = new Base();
b.iNoEnc=2;
System.out.println(b.iNoEnc);
}//End of main
}

Nota que ésta no es la manera generalmente sugerida ya que no permite ninguna separación
entre la interfase y implementación del código. Si decidieras cambiar el tipo de dato de
iNoEnc, tendrías que modificar la implementación de cada parte del código externo que lo
modifica.

Protected

El modificador protected es una pequeña rareza. Una variable protegida es visible dentro de
una clase, en una subclase, y en el mismo paquete, pero no en otra parte. La cualidad de ser
visible dentro del mismo paquete puede darle más visibilidad de la que podrías sospechar.
Cualquier clase que este en el mismo directorio se considera que está en el paquete
predefinido, y así las clases protegidas serán visibles. Esto significa que una variable
protegida es más visible que una variable definida sin modificador de acceso.

Se dice que una variable definida sin modificador de acceso tiene visibilidad predefinida.
La visibilidad predefinida significa una variable puede verse dentro de la clase, y desde otra
parte dentro del mismo paquete, pero no desde una subclase que no este en el mismo
paquete.
Static

Static no es directamente un modificador de visibilidad, aunque en la práctica tiene este


efecto. El modificador static puede aplicarse a una clase, a un método y una variable.
Marcando una variable como estática indica que sólo una copia de esa variable existirá por
clase. Esto está en contraste con los variables normales donde por ejemplo una copia de una
variable integer pertenece a cada instancia de una clase. Así en el ejemplo siguiente tres
instancias del integer no estático iMyVal existirán y cada instancia puede contener un valor
diferente.

class MyClass{
public int iMyVal=0;
}
public class NonStat{
public static void main(String argv[]){
MyClass m1 = new MyClass();
m1.iMyVal=1;
MyClass m2 = new MyClass();
m2.iMyVal=2;
MyClass m3 = new MyClass();
m3.iMyVal=99;
//Esto mostrará 1. Ya que cada instancia de
// la clase tiene su propia copia de MyVal
System.out.println(m1.iMyVal);
}//End of main
}

El Ejemplo siguiente muestra que pasa cuando tienes múltiples instancias de una clase que
contiene una variable estática integer.

class MyClass{
public static int iMyVal=0;
}//End of MyClass
public class Stat{
public static void main(String argv[]){
MyClass m1 = new MyClass();
m1.iMyVal=0;
MyClass m2 = new MyClass();
m2.iMyVal=1;
MyClass m3 = new MyClass();
m2.iMyVal=99;
//Debido a que iMyVal es static,
//hay sólo una copia de él no importa
//cuantas instancias de la clase se creen.
//Este código mostrará el valor de 99
System.out.println(m1.iMyVal);
}//End of main
}
Ten presente que no puedes acceder variables no estáticas desde dentro de un método
estático. Así lo siguiente causará un error en tiempo de compilación.

public class St{


int i;
public static void main(String argv[]){
i = i + 2;//Causará un error al compilar
}
}

Un método estático no puede ser sobreescrito para ser no estático en una clase hija.

Un método estático no puede ser sobreescrito para ser no estático en una clase hija. No hay
ninguna regla similar con referencia a la sobrecarga. El código siguiente causará un error
cuando intentes sobreescribir el método amethod de la clase Base para ser no estático.

class Base{
public static void amethod(){
}
}
public class Grimley extends Base{
public void amethod(){}//Causa un error en tiempo de
compilación
}

El compilador Jikes de IBM produce el siguiente error:

Found 1 semantic error compiling "Grimley.java":


6. public void amethod(){}
<------->
*** Error: The instance method "void amethod();"
cannot override the static method "void amethod();"
declared in type "Base"

Native

El modificador native sólo se usa para los métodos e indica que el cuerpo del código esta
escrito en un lenguaje que no es Java como C y C++. Se escriben a menudo métodos
nativos para propósitos específicos de la plataforma como acceder a algún elemento de
hardware del cual la Maquina Virtual de Java no este consciente. Otra razón es donde se
requiere mayor performance.

Un método nativo termina con punto y coma en lugar de un bloque del código. Así lo
siguiente llamaría una rutina externa, escrita quizás en C++,
public native fastcalc();

Abstract

Es fácil pasar por alto el modificador abstract y perderse algunas de sus implicaciones. Es
la clase de modificador que a los examinadores les gusta para hacer preguntas complicadas.

El modificador abstracto puede aplicarse a las clases y a los métodos. Cuando se aplica a un
método indica que éste no tendrá cuerpo (sin llaves) y el código sólo puede ejecutarse
cuando se implemente en una clase hija. Sin embargo hay algunas restricciones sobre
cuando y donde puedes tener métodos abstractos y reglas sobre las clases que los contienen.
Cuando se aplica a una clase, indica que la clase tiene un método abstracto por lo menos.

Si una clase tiene algún método abstracto este debe ser declarado abstracto por si
mismo.

Sin embargo, no te distraigas pensado que una clase abstracta no puede tener métodos no
abstractos. Cualquier clase que descienda de una clase abstracta debe implementar los
métodos abstractos de la clase base o debe declararlos abstractos ella misma. ¿Tienden
estas reglas a pedir la pregunta por qué querrías crear métodos abstractos?

Los métodos abstractos son principalmente beneficiosos a los diseñadores de clases.


Ofrecen al diseño de una clase una manera de crear un prototipo para métodos que han de
ser implementados, pero la implementación real queda a las personas que usan las clases
después. Aquí hay un ejemplo de una clase abstracta con un método abstracto. De nuevo
nota que la propia clase se declara abstracta, de otra manera habría ocurrido un error en
tiempo de compilación.

Final

El modificador final indica que un método no puede ser heredado. Otra manera de entender
esto es que una clase final no puede ser una clase padre. Cualquier método en una clase
final es automáticamente final. Esto puede ser útil si no quieres que otros programadores
"echen a perder tu código". Otro beneficio es la eficacia puesto que el compilador tiene
menos trabajo al trabajar con un método final. Esto se cubre mejor en el Volumen 1 de
Core Java.

El código siguiente ilustra el uso del modificador final en una clase. Este código mostrará la
cadena "amethod":

final class Base{


public void amethod(){
System.out.println("amethod");
}
}
public class Fin{
public static void main(String argv[]){
Base b = new Base();
b.amethod();
}
}

Shynchronized

La palabra clave synchonized se usa para prevenir que más de un threadπ acceda a un
bloque de código a la vez. Ve la sección 7 sobre threads para entender más cómo funciona
esto.

Transient

La palabra clave transient es uno de los modificadores frecuentemente menos usados.


Indica que una variable no debe escribirse fuera cuando una clase es serializada.

Volatile

Probablemente no conseguirás realizar alguna pregunta sobre la palabra clave volatile. Lo


peor que conseguirás es reconocer que realmente es un palabra clave de Java. Según Barry
Boone:

"le dice al compilador que una variable puede cambiar asincrónicamente debido a los
threads"

Acepta que es parte del lenguaje y entonces mejor preocúpate por otras cosas.

Usando modificadores en combinación


Los modificadores de visibilidad no pueden usarse en combinación, así una variable no
puede ser privada y pública, pública y protegida o protegido y privada. Puedes tener
combinaciones de los modificadores de visibilidad y los modificadores mencionados, por
supuesto, en mi lista "y demás".

• • native
• • transient
• • synchronized
• • volatile

Así puedes tener un método public static native.

p
NT. Aunque algunos documentos traducen thread como hilo o hebra, se esta haciendo común dejarlo tal
cual.
Donde pueden usarse los modificadores
Modificador Método Variable clase
public si si si
private si si si(anidable)
protected si si si(anidable)
abstract si no si
final si si si
transient no si no
native si no no
volatile no si no

Ejercicio 1)
Crea un archivo llamado Whitley.java. En este archivo define una clase llamada Base con
un método abstracto llamado lamprey que retorne un valor de tipo int. En el mismo
archivo crea una clase llamada Whitley que descienda de la clase Base. Proporciona a la
clase Whithley un método llamado lamprey con el código necesario para mostrar en
pantalla la cadena “lamprey”.

Crea un método nativo para la clase llamado mynative. Ahora compila y ejecuta el código.

Ejercicio 2)
Crea una clase publica llamada Malvern. Crea una clase interna y privada llamada Great
que tenga un método llamado show de la forma public void. Haz que este método muestre
en pantalla la cadena “Show”. Proporciona a la clase Malvern un método publico llamado
go que cree una instancia de Great y después de ser instanciada llame al método show. En
el método main de Malvern crea una instancia de sí mismo. Haz que la instancia de sí
mismo llame al método go. Compila y ejecuta el código.

Solución sugerida para el ejercicio 1.

abstract class Base{


abstract int lamprey();
}
public class Whitley extends Base{
public static void main(String argv[]){

}
public int lamprey(){
System.out.println("lamprey");
return 99;
}
native public void mynative();
}
Solución sugerida para el ejercicio 2.

public class Malvern{


public static void main(String argv[]){
Malvern m = new Malvern();
m.go();
}
public void go(){
Great g = new Great();
g.show();
}
private class Great{
public void show(){
System.out.println("Show");
}
}
}

Preguntas.

Pregunta 1)
¿Qué pasará cuando intentes compilar y ejecutar este código?

abstract class Base{


abstract public void myfunc();
public void another(){
System.out.println("Another method");
}
}
public class Abs extends Base{
public static void main(String argv[]){
Abs a = new Abs();
a.amethod();
}
public void myfunc(){
System.out.println("My func");
}
public void amethod(){
myfunc();

}
}
1) 1) El código se compilara y se ejecutara, mostrando la cadena “My func”
2) 2) El código indicara que la clase Base no tiene métodos abstractos.
3) 3) El código se compilara pero indicará un error en tiempo de ejecución (run time
error): la clase base no tiene métodos abstractos
4) 4) El compilador indicara que el método myfunc en la clase Base no tiene cuerpo.

Pregunta 2)
¿Qué pasara cuando intentes compilar y ejecutar este código?

public class MyMain{


public static void main(String argv){
System.out.println("Hello cruel world");
}
}

1) 1) El compilador indicara que main es una palabra reservada y no puede ser usada
para nombrar una clase.
2) 2) El código se compilará y cuando se ejecute mostrara en pantalla la cadena
“Hello cruel world”.
3) 3) El código se compilara pero indicará un error en tiempo de ejecución: el
constructor no esta definido.
4) 4) El código se compilara pero indicara que la función main no esta definida
correctamente.

Pregunta 3)
¿De los siguientes cuales son modificadores de Java?

1) 1) public
2) 2) private
3) 3) friendly
4) 4) transient

Pregunta 4)
¿Qué pasará cuando intentes compilar y ejecutar este código?

class Base{
abstract public void myfunc();
public void another(){
System.out.println("Another method");
}
}
public class Abs extends Base{
public static void main(String argv[]){
i
NT. El verbo utilizado originalmente es complain que significa: quejarse o demandar, espero me indiquen
si con la palabra indicar se entiende mejor el enunciado.
Abs a = new Abs();
a.amethod();
}
public void myfunc(){
System.out.println("My func");
}
public void amethod(){
myfunc();

}
}

1) 1) El código se compilara y se ejecutara, mostrando la cadena “My func”


2) 2) El compilador indicara que la clase Base no esta declarada como abstracta.
3) 3) El código se compilara pero indicará un error en tiempo de ejecución: la clase
base no tiene métodos abstractos
4) 4) El compilador indicara que el método myfunc en la clase Base no tiene cuerpo.

Pregunta 5)
¿Para que defines un método como nativo?

1) 1) Para conseguir acceder a Hardware desconocido por Java


2) 2) Para definir un nuevo tipo de dato como un entero sin signo.
3) 3) Para escribir código optimizado para el mejor desempeño en un lenguaje como
C/C++.
4) 4) Para superar la limitación del alcance privado de un método

Pregunta 6)
¿Qué pasará cuando intentes compilar y ejecutar este código?

class Base{
public final void amethod(){
System.out.println("amethod");
}
}
public class Fin extends Base{
public static void main(String argv[]){
Base b = new Base();
b.amethod();
}
}

1) 1) Un error en tiempo de compilación (compile time error) indicando que una


clase con algún método final debe ser declarado final por si misma.
2) 2) Un error en tiempo de compilación indicará que no puedes heredar de una clase
con métodos final
3) 3) Un error en tiempo de ejecución indicando que Base no esta definida como
final
4) 4) Éxito en la compilación y al ejecutarse mostrará en pantalla “amethod”.

Pregunta 7)
¿Qué pasará cuando intentes compilar y ejecutar este código?

public class Mod{


public static void main(String argv[]){
}
public static native void amethod();
}

1) 1) Error en la compilación: Método nativo no puede ser static.


2) 2) Error en la compilación: método nativo debe retornar algún valor.
3) 3) Compilación correcta pero habrá un error en tiempo de ejecución a menos que
hallas hecho código para hacer útil el método nativo.
4) 4) Compilación y ejecución sin error.

Pregunta 8)
¿Qué pasará cuando intentes compilar y ejecutar este codigo?

private class Base{}


public class Vis{
transient int iVal;
public static void main(String elephant[]){
}
}

1) 1) Un error en tiempo compilación: la clase Base no puede ser privada.


2) 2) Un error en tiempo de compilación indicando que un entero no puede ser
transient
3) 3) Un error en tiempo de compilación indicando que transient no es un tipo de
dato.
4) 4) Un error en tiempo de compilación indicando que el método main esta
deformado

Pregunta 9)
¿Qué pasara cuando intentes compilar y ejecutar estos dos archivos en el mismo directorio?

//Archivo P1.java
package MyPackage;
class P1{
void afancymethod(){
System.out.println("What a fancy method");
}
}
//Archivo P2.java
public class P2 extends P1{
afancymethod();
}

1) 1) ambos se compilarán y P2 mostrará en pantalla “Wath a fancy method” cuando


se ejecute.
2) 2) No se compilará ninguno.
3) 3) Ambos se compilarán pero P2 tendrá un error en tiempo de ejecución.
4) 4) P1 se compilará limpiamente pero P2 tendrá un error al compilarse.

Pregunta 10)
¿Cuáles de las declaraciones siguientes son legales?

1) 1) public protected amethod(int i)


2) 2) public void amethod(int i)
3) 3) public void amethod(void)
4) 4) void public amethod(int i)

Respuestas.

Respuesta 1)
1) 1) El código se compilara y se ejecutara, mostrando la cadena “My func”

Una clase abstracta puede tener métodos no abstractos, pero cualquier clase que descienda
de ella, debe implementar todos los métodos abstractos.

Respuesta 2)

1) 1) El código se compilara pero indicara que la función main no esta definida


correctamente.

La función main recibe un String en lugar de un array de String que es lo correcto.

Respuesta 3)

1) public
2) private
4) transient

Aunque algunos textos usan la palabra “friendly” cuando tratan el tema de visibilidad, esta
no es una palabra reservada de Java. Toma en cuenta que será casi seguro que el examen
contenga problemas que te pidan que identifiques palabras claves de Java en una lista.
Respuesta 4)

2) 2) El compilador indicara que la clase Base no esta declarada como abstracta.

El mensaje de error utilizando JDK 1.1. es:

Abs.java:1: class Base must be declared abstract.


It does not define void myfunc
() from class Base.
class Base{
^
1 error

Respuesta 5)

1) Para conseguir acceder a Hardware desconocido por Java


3) Para escribir código optimizado para el mejor desempeño en un lenguaje como C/C++

Aunque la creación de código “PURE JAVA”es altamente conveniente, particularmente


para permitir la independencia de plataforma, no debe de tomarse como una religión, y hay
ocasiones en que el código nativo se requiere.

Respuesta 6)

4)Éxito en la compilación y al ejecutarse mostrará en pantalla “amethod”.

Este código llama a una versión de amethod de la clase Base. Si intentas implementar una
versión sustituida del método en la clase Fin conseguirás un error en tiempo de
compilación.

Respuesta 7)

4)Compilación y ejecución sin error.

Esta línea no es una llamada a un método nativo –solo se esta declarando- y por lo tanto no
ocurre un error en la ejecución.

Respuesta 8)

1)Un error en tiempo compilación: la clase Base no puede ser privada.

Una clase de un nivel alto, al igual que una clase base, no puede ser declarada como
privada

Respuesta 9)

4)P1 se compilará limpiamente pero P2 tendrá un error al compilarse.


Aunque P2 esta en el mismo directorio que P1, debido a que P1 fue declarado como parte
de un paquete, P1 no esta visible para P2.

Respuesta 10)

2)public void amethod(int i)

Si pensaste que la opción 3 es legal utilizando como parámetro el argumento void, debes
quitarte un poco de C/C++ de la cabeza.
La opción 4 no es legal porque el tipo de datos debe aparecer después de cualquier
especificador de acceso.

Otras Fuentes para este tema.


Este tema es cubierto en el tutorial de Sun como Modificadores de clases:
http://java.sun.com/docs/books/tutorial/reflect/class/getModifiers.html
Controlando el acceso a los miembros de una clase:
http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

Richard Baldwin Cubre este tema en


http://www.Geocities.com/Athens/Acropolis/3797/Java040.htm

Jyothi Krishnan en:


http://www.geocities.com/SiliconValley/Network/3693/obj_sec1.html#obj2

Bruce Eckel Thinking in Java


Chapter 5 (aunque tiene la cabeza llena de C++ e insiste en incluir el modificador “friendly”
Objetivo 3.

Para una clase dada, determinar si un constructor predefinido debe ser creado, y si ese es el
caso, declara el prototipo de ese constructor.

Nota de este objetivo

Éste es un objetivo pequeño pero oportuno, que se concentra en un aspecto fácilmente


pasado por alto en Java

¿Qué es un constructor?

Necesitas comprender el concepto de constructor para entender este objetivo. Brevemente,


es el código que se ejecuta automáticamente cuando se crea la clase. Los constructores a
menudo se usan para iniciar valores en la clase. Los constructores tiene el mismo nombre
de a clase y no retornan ningún valor. En el examen puedes recibir preguntas sobre métodos
que tengan el mismo nombre de la clase pero que retornan algún tipo, como int o String.
Ten cuidado y asegúrate que cualquier método que asumas que es un constructor no debe
retornar algún tipo de dato.

Aquí hay un ejemplo de una clase con un constructor que muestra "Greetings from Crowle"
cuando una instancia de la clase es creada.

public class Crowle{


public static void main(String argv[]){
Crowle c = new Crowle();
}
Crowle(){
System.out.println("Greetings from Crowle");
}
}

¿Cuándo proporciona Java el constructor predefinido?

Si no defines específicamente algún constructor, el compilador inserta “fuera de escena” un


constructor invisible con cero parámetros, frecuentemente esto solo es de importancia
teórica, pero lo verdaderamente importante es que solo recibes el constructor predefinido
con cero parámetros si no creas algún constructor propio.
Si creas tus propios constructores, Java ya no te proporciona el constructor
predefinido con cero parámetros. Así que tienes que especificarlo.

En cuanto creas algún constructor propio, pierdes el constructor predefinido con cero
parámetros. Si intentas crear una instancia de una clase, sin pasarle algún parámetro
(invocando la clase con el constructor con cero parámetros), obtendrás un error. Así, cuando
crees algún constructor para una clase necesitarás crear el constructor con cero parámetros.
Esta es una de las razones por las que generadores de código como Borland/Inprise o
JBuilder, crean un constructor con cero parámetros cuando generan el esqueleto de una
clase.

El ejemplo siguiente muestra código que no compilará. Cuando el compilador verifica la


creación de la instancia c de la clase Base, inserta una llamada al constructor con cero
parámetros. Debido a que la clase base tiene un constructor que recibe un entero, el
constructor con cero parámetros ya no esta disponible. Esto se puede arreglar creando en la
clase Base un constructor con cero parámetros que “no haga nada”.

//Advertencia: no se compilará
class Base{
Base(int i){
System.out.println("single int constructor");
}
}

public class Cons {


public static void main(String argv[]){
Base c = new Base();
}
}

//Esto si se compilará
class Base{
Base(int i){
System.out.println("single int constructor");
}
Base(){}
}

public class Cons {


public static void main(String argv[]){
Base c = new Base();
}
}
El prototipo del constructor predefinido

El objetivo te pide que seas consciente del prototipo del constructor predefinido.
Naturalmente no debe tener ningún parámetro. La predefinición más evidente es no tener
ningún especificador de alcance, pero puedes definir un constructor como público o
protegido.

Los constructores no pueden ser nativos (native), abstractos (abstract), estáticos (static),
sincronizados (synchronized) ni final (final)

Ese pedazo de información se derivó directamente de un mensaje de error del compilador.


Parece que la calidad de los mensajes de error están mejorando con las nuevas versiones de
Java. He oído que el nuevo compilador de Java de IBM tiene un buen informador de
errores. Podrían aconsejarte que tuvieras disponible más de una versión del compilador de
Java para verificar tu código y cazar los errores.

Ejercicios

Ejercicio 1)
Crea una clase llamada Salwarpe con un método llamado hello que muestre la cadena
“hello”. En el método main de la clase crea una instancia de si misma llamada s1 y llama al
método hello desde la instancia. Compila y ejecuta el programa para que puedas ver el
resultado.

Ejercicio 2)
Usando todavía el archivo Salwarpe.java comenta las líneas que crean la instancia y llaman
al método hello. Crea un constructor publico para la clase que tome un parámetro entero y
muestre el valor del entero. Crea una instancia de la clase llamada s2 proporciónale el
valor de 99 al constructor. Compila y ejecuta el programa para que puedas ver mostrado el
resultado.

Ejercicio 3)
Descomenta las líneas que crean la instancia s1 y modifica el programa para que compile,
ejecute y muestre ambos la cadena Hello y el numero 99.

Solución sugerida para el ejercicio 1.

public class Salwarpe {


public static void main(String argv[]){
Salwarpe s1 = new Salwarpe();
s1.hello();
}
public void hello(){
System.out.println("Hello");
}
}
Solución sugerida para el ejercicio 2.

public class Salwarpe {


public static void main(String argv[]){
//Salwarpe s1 = new Salwarpe();
//s1.hello();
Salwarpe s2 = new Salwarpe(99);
}
public void hello(){
System.out.println("Hello");
}
public Salwarpe(int i){
System.out.println(99);
}
}

Solución sugerida para el ejercicio 3.

public class Salwarpe {


public static void main(String argv[]){
Salwarpe s1 = new Salwarpe();
s1.hello();
Salwarpe s2 = new Salwarpe(99);
}
public void hello(){
System.out.println("Hello");
}
public Salwarpe(int i){
System.out.println(99);
}
public Salwarpe(){}
}

Nota como fue necesario crear el constructor con cero parámetros para este último
ejercicio. Una vez que has creado algún constructor para una clase, Java ya no te
proporciona “tras escena” el constructor con cero parámetros que estaba disponible en el
ejercicio 1.

Preguntas

Pregunta 1)
Dada la siguiente definición de clase:

class Base{
Base(int i){}

}
class DefCon extends Base{
DefCon(int i){
//XX
}
}

¿Cuál se las líneas siguientes será individualmente valida si se sustituye por la línea
marcada con //XX?

1) super();
2) this();
3) this(99);
4)super(99);

Pregunta 2)
Dada la siguiente definición de clase:

public class Crowle{


public static void main(String argv[]){
Crowle c = new Crowle();
}
Crowle(){
System.out.println("Greetings from Crowle");
}
}

¿Cuál es el tipo de dato retornado por el constructor?

1) null
2) integer
3) String
4) no es retornado algún tipo de dato

Pregunta 3)

¿Qué pasara cuando intentes compilar y ejecutar el siguiente código?

public class Crowle{


public static void main(String argv[]){
Crowle c = new Crowle();
}
void Crowle(){
System.out.println("Greetings from Crowle");
}
}

1)Se compilara y mostrará la cadena “Greetings from Crowle”.


2)Error en tiempo de compilación: un constructor no puede retornar un tipo de dato.
3)Se compilara y mostrará la cadena “void”.
4)Se compilara y no mostrará nada al ejecutarse.

Pregunta 4)
¿Qué pasara cuando intentes compilar y ejecutar el siguiente código?

class Base{
Base(int i){
System.out.println("Base");
}

}
class Severn extends Base{
public static void main(String argv[]){
Severn s = new Severn();
}
void Severn(){
System.out.println("Severn");
}
}

1)Se compilará y mostrará la cadena “Seven” al ejecutarse.


2)Error en tiempo de compilación.
3)Se compilará y no mostrará nada al ejecutase
4)Se compilará y mostrará la cadena “Base”

Pregunta 5)

¿Cuál de las siguientes declaraciones son verdaderas?

1)El constructor predefinido retorna un tipo void.


2)El constructor predefinido toma como parámetro un valor tipo void.
3)El constructor predefinido no toma parámetros.
4)El constructor predefinido no se crea si la clase contiene algún constructor propio

Respuestas

Respuesta 1)
4)super (99)

Debido a que la clase Base tiene definido un constructor, el compilador no insertará el


constructor predefinido con cero parámetros. Por consiguiente, llamar a super() causará un
error. Una llamada a this( ) es un intento de llamar a un constructor con cero parámetros
inexistente en la clase actual. La llamada a this(99) causará una referencia circular y
causará un error en tiempo de compilación.

Respuesta 2)

4) no es retornado algún tipo de dato

Debe ser bastante obvio de que ningún tipo de dato es retornado, así como por definición
los constructores no tienen tipos de datos

Respuesta 3)

4)Se compilara y no mostrará nada al ejecutarse.

Debido a que el método Crowle retorna un tipo de dato no es un constructor, Por


consiguiente la clase se compilara y al ejecutarse el método Crowle no se ejecutará –pues
no ha sido llamado-.

Respuesta 4)

2)Error en tiempo de compilación.

Un error ocurre cuando la clase Severn intenta llamar al constructor con cero parámetros en
la clase Base.

Respuesta 5)

3)El constructor predefinido no toma parámetros.


4)El constructor predefinido no se crea si la clase contiene algún constructor propio

Otras Fuentes de este tema:


Esta tema es cubierto en el Tutorial de Sun :
http://java.sun.com/docs/books/tutorial/java/javaOO/constructors.html
Richard Baldwin cubre este tema en
http://www.Geocities.com/Athens/Acropolis/3797/Java042.htm#default constructor
Jyothi Krishnan en:
http://www.geocities.com/SiliconValley/Network/3693/obj_sec1.html#obj3
Bruce Eckel Thinking In Java
Chapter 4
Objetivo 4
Establecer los tipos de datos validos de retorno para cualquier método, dada las
declaraciones de todos lo métodos relacionados con este o con la clase padre.

Nota de este objetivo


La frase del objetivo parece ser bastante obscura. Parece estar pidiéndote que entiendas la
diferencia entre sobrecarga y sobrescritura.

Para aprovechar mejor este objetivo necesitas una comprensión básica sobre la sobrecarga y
sobrescritura de métodos. Esto se ve en la:

Sección 6: Orientación a Objetos y Sobrecarga y Sobreescritura en Tiempo de Ejecución

Métodos en la misma clase


Si dos o más métodos en la misma clase tienen el mismo nombre, se dice que el método
esta sobrecargado. Puedes tener dos métodos en una clase con el mismo nombre pero
deben tener parámetros de diferente tipo y en diferente orden.

Es el orden de los parámetros y los tipos de los mismos los que distinguen entre cualquiera
de dos versiones de un método sobrecargado a uno en especial. El tipo de dato de retorno
no contribuye a la distinción entre métodos.

El código siguiente generará un error en tiempo de compilación, el compilador observa en


amethod un intento por definir el mismo método dos veces. Causa un error que dirá algo
como lo siguiente:

method redefined with different return type: void amethod(int)


was int amethod(int)

class Same{
public static void main(String argv[]){
Over o = new Over();
int iBase=0;
o.amethod(iBase);
}
//Las siguientes definiciones generan un error al compilar
public void amethod(int iOver){
System.out.println("Over.amethod");
}
public int amethod(int iOver){
System.out.println("Over int return method");
return 0;
}

}
El tipo de dato de retorno no contribuye a realizar la distinción
entre un método y otro.

Métodos en una subclase.

Puedes sobrecargar un método en una subclase. Todo lo que se requiere es que la nueva
versión debe tener parámetros de diferente tipo y en diferente orden. Los nombres de los
parámetros o el tipo de dato retornado por el método no se toman en cuenta para la
sobrecarga de métodos.

Si vas a sobrescribir un método, por ejemplo para reemplazar su funcionalidad


completamente en una subclase, la versión sobrescrita del método debe tener la misma
definición que la versión de la clase base de la que esta descendiendo. Esto incluye el tipo
de dato de retorno. Si creas un método en una subclase con el mismo nombre y definición
pero retorna un tipo de dato distinto, generarás el mismo mensaje de error que en el
ejemplo anterior. Es decir:

method redefined with different return type: void amethod(int)


was int amethod(int)

El compilador lo ve como un intento fallido por sobrecargar el método en lugar de verlo


como una sobrescritura del método.

Preguntas

Pregunta 1)

Dada la siguiente definición de clase:

public class Upton{


public static void main(String argv[]){

}
public void amethod(int i){}
//Here
}
¿Cuáles de las líneas siguientes son válidas para ser colocadas después del comentario
//Here?

1) public int amethod(int z){}


2) public int amethod(int i,int j){return 99;}
3) protected void amethod(long l){ }
4) private void anothermethod(){}

Pregunta 2)

Dada la siguiente definición de clase:

class Base{
public void amethod(){
System.out.println("Base");
}
}
public class Hay extends Base{
public static void main(String argv[]){
Hay h = new Hay();
h.amethod();
}

¿Cuál de los siguientes método puede ser de la clase Hay para que compile y provoque que
el programa muestre la cadena “Hay” ?

1) public int amethod(){ System.out.println("Hay");}


2) public void amethod(long l){ System.out.println("Hay");}
3) public void amethod(){ System.out.println("Hay");}
4) public void amethod(void){ System.out.println("Hay");}

Respuestas

Respuesta 1)

2) public int amethod(int i, int j) {return 99;}


3) protected void amethod (long l){}
4) private void anothermethod(){}

La opción 1 no compilara por dos razones. La primera es que obviamente exige que un
entero sea retornado- y como podemos ver hace falta un return -. La otra es que es
evidente un intento por redefinir un método dentro de la misma clase. El cambio de nombre
del parámetro de i a z no tiene efecto y un método no puede ser sobrescrito dentro de la
misma clase.

Respuesta 2)

3) public void amethod(){ System.out.println("Hay");}

La opción 3 es una sobrescritura del método de la clase Base, para alguna invocación de
esta versión se utilizarán cero parámetros

La opción 1 generará un error que indicará que se está intentando redefinir un método con
un diferente tipo de dato de retorno. Aunque la opción 2 compilará, la llamada a amethod( )
invocará el método de la clase Base y la salida sea la cadena “Base”. La opción 4 fue
diseñada para sorprender a aquellos con una cabeza llena de C/C++, en Java no hay tal
cosa: la utilización de void para indicar que no hay parámetros.

Otras Fuentes de este tema:

Jyothi Krishnan
http://www.geocities.com/SiliconValley/Network/3693/obj_sec1.html#obj4

En esta liga Jyothi sugiere que vayas al objetivo 19:


http://www.geocities.com/SiliconValley/Network/3693/obj_sec6.html#obj19

Você também pode gostar