Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Mensajes - Kabuto

Páginas: 1 2 [3] 4 5 6 7 8 ... 50
42
Aprender a programar desde cero / Re: Interfaces
« en: 16 de Junio 2023, 02:23 »
A ver, primero hacemos que Carta implemente la interfaz Comparable

Si lo hacemos así:
Citar
public class Carta implements Comparable {

No estamos especificando con que clase puede compararse y por lo tanto el método compareTo() que hay que implementar, pedirá recibir un objeto de clase Object
Object es algo así como la superclase suprema de la que TODAS las clases Java son hijas, sí o sí...
Citar
   @Override
   public int compareTo(Object o) {
      // Código para comparar cartas
      return 0;
   }
}


Se puede hacer así, si nos interesase que una Carta pudiera compararse con cualquier otra cosa, aunque no sea una Carta

Pero no es lo que nos interesa, mejor si especificamos al implementar la interfaz, que la clase Carta se ha de comparar, pues con otras Cartas y no con cualquier cosa...
Citar
public class Carta implements Comparable<Carta> {

Ahora sí, el método que hay que implementar, pedirá recibir un objeto Carta, que es lo único con lo que va a poder compararse.

Citar
   @Override
   public int compareTo(Carta otraCarta) {
      // Código para comparar cartas
      return 0;
   }

Bien, ahora hay que escribir el cuerpo de ese método.
Dijimos que una Carta, por defecto, se ha ordenar de forma natural, primero por orden de palo y luego por orden de valor de carta.
Es decir, usamos la misma lógica que usamos en la clase OrdPalNumInc, solo hay que adaptar un poco el código.
Seguimos teniendo que usar el "truco" de acceder al array público de la clase Baraja para saber el valor aritmético de cada carta, ya que el atributo "valor" de la clase Carta es un String, y no un int/Integer.
Es un poco chapuza, la clase Carta debería ser capaz de poder compararse sin tener que recurrir a elementos de otra clase.
Pero no nos queda otra, no hemos decidido nosotros los atributos de esta clase.

Este sería el código:
Código: [Seleccionar]
@Override
public int compareTo(Carta otraCarta) {
if (otraCarta.equals(this)) {
return 0; //Cartas son iguales
}
else {
if (this.palo.equals(otraCarta.palo)) {
//Mismo palo, el orden depende del valor de las cartas
/*
        * El atributo "numero" de las Cartas es un String, no es un Integer.
        * Esto significa que no podemos comparar directamente esos atributos, porque en realidad
        * no son números, y necesitamos lograr un orden aritmético.
        *
        * Por suerte, la clase Baraja tiene un array público con los nombres de estos "números"
        * en el orden correcto.
        * Así que podemos usar la posición que ocupa cada "nombre de número" en el array para obtener
        * unos valores enteros con los que poder comparar de forma aritmética
        */
int posiC1 = 0, posiC2 = 0;
        for (int i = 0; i < Baraja.numeros.length; i++) {
        if (this.numero.equals(Baraja.numeros[i]))
        posiC1 = i;
        if (otraCarta.numero.equals(Baraja.numeros[i]))
        posiC2 = i;
        }
        //Tenemos sus posiciones numéricas, podemos compararlas para decidir el orden.
        if (posiC1 == posiC2)
        return 0; //Número es igual
        else if (posiC1 < posiC2)
        return -1; //c1 es menor que c2
        else
        return 1; //c2 es menor que c1
}
else //Los palos son distintos, aquí no importa el número de carta, el orden depende los palos
return this.palo.compareTo(otraCarta.palo);//Retornamos la comparación por defecto de Strings
}
}


Bien, gracias a esto, resulta que ahora la clase Mazo ya puede prescindir de aquel atributo que era una clase chusquera, si se me permite el comentario, llamada  AlgoritmoOrdenacion
Citar
public class Mazo {
   
       
      List cartas;
       private AlgoritmoOrdenacion algoritmo;
Podemos quitarle ese atributo y también el método que lo seteaba
Citar
public void setAlgoritmo(AlgoritmoOrdenacion algoritmo) {
           this.algoritmo = algoritmo;
       }

Ahora la clase Carta ya posee su propio algoritmo de ordenación gracias a la interfaz Comparable, así ya puede ordenarse por sí sola mediante este método:
Código: [Seleccionar]
public class Mazo {


List cartas;

    public void ordena() {
    cartas.sort(null);
    }

Como dije antes, si al List que contiene las cartas le pedimos que las ordene invocando su método sort() y a este le indicamos valor null como argumento, entonces el List aplicará el algoritmo de ordenación que tienen las propias Cartas

Si lo probamos con un nuevo Main, veremos que el mazo se ordena correctamente de forma "natural":
Código: [Seleccionar]
public class Main {

public static void main(String[] args) {

Baraja baraja = new Baraja();
        Mazo mazo = baraja.getMazo();
        System.out.println("Baraja original: ");
        System.out.println(mazo.toString());
       
        mazo.ordena();
        System.out.println("\nOrdenado NATURAL(por palo y numero incrementando): ");
        System.out.println(mazo.toString());

}

}


OK, pero esto es solo la primera parte de lo que nos piden.
Lo que también se desea, es que la clase Mazo sobrecargue el método ordena() de forma que podamos enviarle de forma externa un objeto que implemente un Comparator, es decir, una forma de enviarle algoritmos de ordenación distintos al que posee la clase Carta
Citar
public class Mazo {
       
      List cartas;

       public void ordena() {
          cartas.sort(null);
       }
      
       public void ordena(Comparator comparador) {
          cartas.sort(comparador);
       }


Pues ahora hay que escribir estas distinas clases que implementen Comparator.

Se pueden escribir por separado. Pero, para tener un poco más de orden, se puede crear una sola clase que en su interior tengamos anidadas estas otras clases de tipo Comparator

Podemos empezar con la clase que ordena de forma natural, pero decreciente.
Es decir, primero ordena por palos y luego por número de carta, pero esta vez, el número de carta se ordenará de mayor a menor..
El código es prácticamente el mismo de antes, pero invirtiendo los valores que se retornan al comparar número para hacer que sea decreciente, en lugar de creciente:
Código: [Seleccionar]
import java.util.Comparator;

public class ComparadoresDeCartas {

//Primer algortimo alternativo de ordenacion
public static class PorPaloYNumeroDecreciente implements Comparator<Carta> {

@Override
public int compare(Carta carta1, Carta carta2) {
if (carta1.equals(carta2)) {
return 0; //Cartas son iguales
}
else {
if (carta1.getPalo().equals(carta2.getPalo())) {
//Mismo palo, el orden depende del valor de las cartas

int posiC1 = 0, posiC2 = 0;
        for (int i = 0; i < Baraja.numeros.length; i++) {
        if (carta1.getNumero().equals(Baraja.numeros[i]))
        posiC1 = i;
        if (carta2.getNumero().equals(Baraja.numeros[i]))
        posiC2 = i;
        }
        //Tenemos sus posiciones numéricas, podemos compararlas para decidir el orden.
        if (posiC1 == posiC2)
        return 0; //Número es igual
        else if (posiC1 < posiC2)
        return 1; //c1 es menor que c2, devolvemos positivo para tener orden decreciente
        else
        return -1; //c2 es menor que c1, devolvemos negativoo para tener orden decreciente
}
else //Los palos son distintos, aquí no importa el número de carta, el orden depende los palos
return carta1.getPalo().compareTo(carta2.getPalo());//Retornamos la comparación por defecto de Strings
}
}

}

}

Fíjate que la clase anidada la declaramos como static. Esto es necesario para poder invocarla sin tener que crear previamente un objeto de clase ComparadoresDeCartas.
Podremos crear directamente objetos de la clase anidada, llamándola así en el Main

Citar
public class Main {

   public static void main(String[] args) {
      
      Baraja baraja = new Baraja();
        Mazo mazo = baraja.getMazo();
        System.out.println("Baraja original: ");
        System.out.println(mazo.toString());
       
        mazo.ordena();
        System.out.println("\nOrdenado NATURAL(por palo y numero incrementando): ");
        System.out.println(mazo.toString());
       
        mazo.ordena(new ComparadoresDeCartas.PorPaloYNumeroDecreciente());
        System.out.println("\nOrdenado por palo y numero decrementando: ");
        System.out.println(mazo.toString());

   }

}

Siguiendo con el ejemplo, a esta clase que hemos creado, podemos añadirle una segunda clase Comparator anidada con otro algoritmo más de ordenación:

Código: [Seleccionar]
public class ComparadoresDeCartas {

//Primer algortimo alternativo de ordenacion
public static class PorPaloYNumeroDecreciente implements Comparator<Carta> {
@Override
public int compare(Carta carta1, Carta carta2) {
if (carta1.equals(carta2)) {
return 0; //Cartas son iguales
}
else {
if (carta1.getPalo().equals(carta2.getPalo())) {
//Mismo palo, el orden depende del valor de las cartas

int posiC1 = 0, posiC2 = 0;
for (int i = 0; i < Baraja.numeros.length; i++) {
if (carta1.getNumero().equals(Baraja.numeros[i]))
posiC1 = i;
if (carta2.getNumero().equals(Baraja.numeros[i]))
posiC2 = i;
}
//Tenemos sus posiciones numéricas, podemos compararlas para decidir el orden.
if (posiC1 == posiC2)
return 0; //Número es igual
else if (posiC1 < posiC2)
return 1; //c1 es menor que c2, devolvemos positivo para tener orden decreciente
else
return -1; //c2 es menor que c1, devolvemos negativoo para tener orden decreciente
}
else //Los palos son distintos, aquí no importa el número de carta, el orden depende los palos
return carta1.getPalo().compareTo(carta2.getPalo());//Retornamos la comparación por defecto de Strings
}
}
}

//Segundo algoritmo de ordenacion
public static class PorNumeroIncrementalYPalo implements Comparator<Carta> {
@Override
public int compare(Carta carta1, Carta carta2) {
if (carta1.equals(carta2)) //Cartas son iguales
return 0;
else {
if (carta1.getNumero() == carta2.getNumero()) //Mismo número, se ordenará por palo
return carta1.getPalo().compareTo(carta2.getPalo());
else {//Distinto número de carta
//Averiguamos el valor de estas cartas según posición en el array
int posiC1 = 0, posiC2 = 0;
for (int i = 0; i < Baraja.numeros.length; i++) {
if (carta1.getNumero().equals(Baraja.numeros[i]))
posiC1 = i;
if (carta2.getNumero().equals(Baraja.numeros[i]))
posiC2 = i;
}
//Tenemos sus posiciones numéricas, podemos compararlas para decidir el orden.
if (posiC1 == posiC2)
return 0; //Número es igual
else if (posiC1 < posiC2)
return -1; //c1 es menor que c2
else
return 1; //c2 es menor que c1
}
}
}
}
}


Y en el Main volvemos a llamarlo del mismo modo:
Citar
public class Main {

   public static void main(String[] args) {
      
      Baraja baraja = new Baraja();
        Mazo mazo = baraja.getMazo();
        System.out.println("Baraja original: ");
        System.out.println(mazo.toString());
       
        mazo.ordena();
        System.out.println("\nOrdenado NATURAL(por palo y numero incrementando): ");
        System.out.println(mazo.toString());
       
        mazo.ordena(new ComparadoresDeCartas.PorPaloYNumeroDecreciente());
        System.out.println("\nOrdenado por palo y numero decrementando: ");
        System.out.println(mazo.toString());
       
        mazo.ordena(new ComparadoresDeCartas.PorNumeroIncrementalYPalo());
        System.out.println("\nOrdenado por numero y palo incrementando: ");
        System.out.println(mazo.toString());

   }

}


Y de esta forma podríamos contener en una única clase, todos los algoritmos de ordenación que se nos ocurriesen.

Y se los podemos hacer llegar al Mazo mediante el método ordena() que hemos "sobrecargado"

Espero que se haya entendido la explicación.

Saludos.

43
Aprender a programar desde cero / Re: Interfaces
« en: 14 de Junio 2023, 12:08 »
Lo que se pide es:
  • Por un lado, que la clase Carta implemente Comparable, haciendo que se ordenen de forma natural, primero por "palos" y luego por "número" de carta.
    Es decir, el mismo orden que usamos para la clase OrdPalNumInc
  • Y por otro lado, crear clases que implementen Comparator(ligeramente distinto a Comparable) donde cada una ordene de formas distintas a la "natural"

Esto es porque, aunque a una clase le enseñemos cómo ha de compararse (mediante Comparable), luego de forma externa podemos hacerle llegar otras reglas de comparación distintas(mediante Comparator)

Por tanto, nos proponen que la clase Mazo tenga dos métodos para ordenar.

Uno de esos métodos no recibe ningún parámetro
Para aplicar este orden, basta con pedirle al List de cartas que se ordene invocando su método sort().

Código: [Seleccionar]
public void ordena() {
    cartas.sort(null);
}

Al darle valor nulo como parámetro, aplicará el orden que digan las propias cartas, que es el que ellas "conocen" gracias a su Comparable.


El otro método, sí recibirá un objeto Comparator y se lo haremos llegar al método sort().
En este caso, ahora no son las cartas quienes deciden su orden, si no que se seguirán las reglas que marquen ese Comparator
Código: [Seleccionar]
public void ordena(Comparator comparador) {
    cartas.sort(comparador);
}
    Resumiendo, has de:
    • Implementar la interfaz Comparable a la clase Carta, para que se ordene de forma "natural"
    • Crear distintas clases que implementen Comparator, donde se apliquen reglas de ordenación distintas a la "natural"(ordenar primero por número y luego por palo, ordenar de forma inversa...
    • Modificar la clase Mazo para que "sobrecargar" el método ordenar(), es decir, el mismo método tendrá dos variantes: la que no recibe parámetros y la que recibe un Comparator

    Inténtalo, y si te atascas, te ayudamos.
    Saludos.

44
La solución parece correcta.

Crear esa clase no era estrictamente necesario, pues en realidad no hace nada que no pueda hacer directamente la clase String.

Sin embargo, al estar en proceso de aprendizaje, está bien para ampliar la práctica y siempre es bueno explorar soluciones distintas, sean óptimas o no.

Es fantástico ver a alguien con estas ganas de aprender  ;)
Saludos.

45
Todo correcto.

Como información extra, la clase String dispone de un método llamado startsWith() a la que se le puede pasar una cadena como argumento y devolverá true si el String sobre el que invocamos este método comienza por esa cadena.
Aunque no "ignora" si la cadena es mayúscula o minúscula, por lo tanto, previamente habrá que convertir el String al mismo formato de letra que tenga la cadena que usamos para consultar.
Puede hacerse encadenando dos métodos seguidos:

Código: [Seleccionar]
        if (entradaTeclado.toLowerCase().startsWith("a")) {
            System.out.println ("SÍ comienza por la letra \"a\"");
        } else {
            System.out.println ("NO comienza por la letra \"a\"");
        }

Pero repito, esto es un dato extra.
El ejercicio pedía resolverse con el método subString(), tal y como tú has hecho, así que todo en orden  ;)

46
Aprender a programar desde cero / Re: Interfaces
« en: 06 de Junio 2023, 18:49 »
Bien, hay que crear una clase BackwardsStringSequenceTokio que será similar a la anterior pero esta vez invertirá el orden de los caracteres.

Dice que el constructor recibe un String. No me queda claro si por tanto, su atributo deberá ser también un String o un array de chars como su clase "hermana".

Yo lo voy a hacer con un String.
En el constructor, lo que hago es construir una cadena invertida a partir del String recibido y es lo que asigno al atributo. Así directamente este objeto ya tiene una cadena invertida.

El resto de métodos que hereda de la interfaz CharSequenceTokio son casi iguales a los de su clase "hermana", solo que adaptados para trabajar con String en lugar de un array de chars.

Hay un detalle importante en el método subSequence().
Al igual que hicimos en la clase "hermana", construimos una subsecuencia a partir del start y end que nos indican y retornamos un objeto de esta misma clase.

Pero está el problema de que en este caso, la clase BackwardsStringSequenceTokio invierte automáticamente la cadena que pide para ser construido.
Por tanto, estaremos retornando una subsecuencia con un orden distinto a la de la cadena de la que estamos extrayendo la subsecuencia.

Para evitarlo, lo que hago es construir esa subsecuencia en orden invertido, para que luego al retornar el objeto, se vuelva a invertir el orden y entonces ya sí la subcadena es retornada en el orden deseado
(Espero haberme explicado bien, es un poco lioso...)
Código: [Seleccionar]
public class BackwardsStringSequenceTokio implements CharSequenceTokio {

private String cadena;

public BackwardsStringSequenceTokio(String cadena) {
//Construimos una cadena invertida a partir del argumento recibido
StringBuilder invertida = new StringBuilder();
for (int i = cadena.length()-1; i >= 0; i--)
invertida.append(cadena.charAt(i));

//La asignamos al atributo
this.cadena = invertida.toString();
}

@Override
public int length() {
return cadena.length();
}

@Override
public char charAt(int index) {
if (index < 0 || index >= length())
return '0';
else
return cadena.charAt(index);
}

@Override
public CharSequenceTokio subSequence(int start, int end) {
//Start no valido
if (start < 0 || start >= length())
return null;
//End no valido
if (end < 0 || end >= length())
return null;
//Start mayor que end
if (start > end)
return null;
//Start es igual que end
if (start == end) {
return new BackwardsStringSequenceTokio("");//String vacío
}
//Indices válidos
/*
* Ahora construiremos una sub cadena y a partir de ella retornaremos
* un objeto BackwardsStringSequenceTokio.
* Sin embargo, estos objetos al crearse automáticamente invierten
* la cadena recibida, así que estaremos retornando una sub cadena
* con un orden distinto del deseado.
* Para evitarlo, vamos a crear la sub cadena usando un bucle invertido
* así al construir el objeto BackwardsStringSequenceTokio
* la subcadena será retornada con el orden deseado.
*/
String subCadena = "";
for (int i = end -1; i >= start; i--)
subCadena += cadena.charAt(i);

return new BackwardsStringSequenceTokio(subCadena);
}

@Override
public String toString() {
return cadena;
}

}


Si la ponemos a prueba con un main como el anterior, veremos que funciona.
La cadena original que le pasamos es invertida automáticamente y las subcadenas que extraemos conservan este orden invertido.
Código: [Seleccionar]
public static void main(String[] args) {

Scanner teclado = new Scanner(System.in);
BackwardsStringSequenceTokio secuencia = new BackwardsStringSequenceTokio("invertida");

System.out.println("Secuencia original: " + secuencia);

System.out.print("\nElija una posicion de la secuencia entre 0 y " + (secuencia.length()-1) +  ": ");
int c1 = teclado.nextInt();
System.out.println("Caracter obtenido: " + secuencia.charAt(c1));

System.out.println("\nElija ahora posiciones de inicio y fin para hacer una subcadena.");
System.out.print("Inicio: ");
int start = teclado.nextInt();
System.out.print("Fin: ");
int end = teclado.nextInt();

BackwardsStringSequenceTokio subCadena = (BackwardsStringSequenceTokio) secuencia.subSequence(start, end);
if (subCadena == null)
System.out.println("Indices no validos");
else {
System.out.println("Subcadena obtenida: " + subCadena);
System.out.println("Longitud de subcadena: " + subCadena.length());
}

System.out.println("\n\t\tFIN DE PROGRAMA");
teclado.close();
}


Resultado en pantalla:
Citar
Secuencia original: aditrevni

Elija una posicion de la secuencia entre 0 y 8: 4
Caracter obtenido: r

Elija ahora posiciones de inicio y fin para hacer una subcadena.
Inicio: 4
Fin: 8
Subcadena obtenida: revn
Longitud de subcadena: 4

      FIN DE PROGRAMA

47
Hola.

A ver, toda la "magia" de contar los días transcurridos ocurre en este bucle
Código: [Seleccionar]
   TD <- 0   // INICIALIZAR ACUMULADOR DE TOTAL DE DIAS
   Para MM <- 1 Hasta M-1 Con Paso 1 Hacer
      Segun MM Hacer
         1,3,5,7,8,10,12: DD <- 31
         4,6,9,11: DD <- 30
         De Otro Modo:
            DD <- 28
      Fin Segun
      TD <- TD + DD   // ACTUALIZAR ACUMULADOR DE TOTAL DE DIAS
   Fin Para

Lo que hace es recorrer los meses completos que hay desde enero hasta el mes de la fecha introducida y acumular los días que tienes cada uno de esos mes.

Algunos meses pueden tener 31 días, otros pueden tener 30 y luego está Febrero que tiene 28 (29 si es año bisiesto, pero esto no se está teniendo en cuenta para simplificar)
Para esto, se usá el "Según...."
Citar
Segun MM Hacer
         1,3,5,7,8,10,12: DD <- 31
         4,6,9,11: DD <- 30
         De Otro Modo: (Febrero)
            DD <- 28
      Fin Segun

Una vez se han acumulado los días de esos meses completos, solo queda sumar los días del último mes "no completo", es decir, los días indicados en la fecha que ha introducido el usuario.

Imagina que nos dan la fecha 05/04/2023.
Comenzamos de momento con 0 días acumulados:
Código: [Seleccionar]
diasAcumulados = 0
Bien, el bucle recorre todos los meses completos hasta el mes indicado, que no estará completo y por tanto no cuenta en el bucle.
Código: [Seleccionar]
Para MM <- 1 Hasta M-1 Con Paso 1 HacerEs decir, nos han dado el mes 4, pues el bucle va a recorrer los meses 1,2 y 3

Empezamos por el mes 1(Enero), ¿cuántos días tiene?.
Pues mediante el "Según..." vemos que tiene 31 días
Citar
Segun MM Hacer
         1,3,5,7,8,10,12: DD <- 31
         4,6,9,11: DD <- 30
         De Otro Modo: (Febrero)
            DD <- 28
      Fin Segun

Por tanto, acumulamos 31 días a los 0 días iniciales.
Código: [Seleccionar]
diasAcumulados = 0 + 31 = 31
Pasamos al siguiente mes, el 2, que el "Según..." nos dice que tiene 28 días más para acumular:
Código: [Seleccionar]
diasAcumulados = 31 + 28 = 59
Llegamos al mes 3, que también tiene 31 días acumulables:
Código: [Seleccionar]
diasAcumulados = 59 + 31 = 90
Ok, ya hemos recorrido todos los meses completos, los 1,2 y 3.
El 4 no está completo, pero como la fecha indicada es 05/04/2023, pues sabemos que de este cuarto mes han transcurrido 5 días, así que los acumulamos también
Código: [Seleccionar]
diasAcumulados = 90 + 5 = 95
Y ya tenemos el resultado. Desde el 01/01/2023 hasta el 05/04/2023, han transcurrido 95 días.


Supongamos estas dos fechas
Inicio = 05/03/2023
Fin = 23/06/02023
Hacer lo mismo entre dos fechas indicadas por el usuario, básicamente es el mismo procedimiento.
Solo cambia que ahora el bucle "Para..." no comienza en el mes 1. Ha de comenzar en el mes indicado en la fecha de inicio (se puede llamar Mi) hasta el mes indicado como fecha final(Mf)


Citar
   Para MM <- Mi Hasta Mf-1 Con Paso 1 Hacer
      Segun MM Hacer
         1,3,5,7,8,10,12: DD <- 31
         4,6,9,11: DD <- 30
         De Otro Modo:
            DD <- 28
      Fin Segun
      TD <- TD + DD   // ACTUALIZAR ACUMULADOR DE TOTAL DE DIAS
   Fin Para

Cuando termine el bucle, igual que en el ejercicio de antes, habrá que sumar a los días acumulados los días indicados en la fecha Final.

Pero además, habrá que RESTAR los días indicados en la fecha de Inicio.
Hemos propuesto como ejemplo esta fecha de inicio: 05/03/2023
En el bucle "Para...", el mes 3 lo hemos contado como si fuera un mes completo y hemos acumulado 31 días para ese mes.
Pero no es correcto, porque la fecha comienza el día 5. Así que esos 5 días habría que restarlos al total acumulado.

Por tanto, al terminar el bucle, al total acumulado hay que sumarle los días de la fecha Final (Df) y restarle el día indicado en la fecha de Inicio(Di).


Otra diferencia es que convendría validar que la fecha que te han dado como fecha Inicial, es realmente anterior a la fecha que te dan como Final.

Pero yo antes que eso, me ocuparía de conseguir hacer bien el cálculo entre dos fechas indicados por el usuario.
Y ya luego, si hubiera tiempo, añadir código para validar las fechas indicadas.

Espero que hayas entendido la lógica de estos procesos. Intenta desarrollar el código y comparte por aquí si no te sale, a ver si podemos ayudarte.

Saludos.

48
OK, perfecto.

En estos casos, se puede simplemente cambiar el nombre de los argumentos para que NO coincidan con el de los atributos y así ahorrarnos tener que usar el this para evitar ambigüedades.

Pero cuando avances y profundices más en Java, ya verás que hay algunos casos distintos a estos donde no hay más alternativa que usar el this.

Un saludo.


49
Esas comidas de coco "tontas" sirve para asentar los conocimientos.
Verás como no vuelves a olvidar las comillas  ::)

Un saludo.

50
Está ok.
El ejercicio es simplemente para comprobar que sabemos buscar los métodos que podamos necesitar dentro de la documentación Java.

51
Hola y bienvenido.

La ayuda que necesites puedes pedirla en el foro público exponiendo el enunciado de tu ejercicio.

He editado tu número de teléfono por los riesgos que supone para ti exponerlo en público(no es buena idea).

Si quieres compartirlo con alguien que se preste ayudarte, hazlo mediante mensaje privado, e-mail u otro medio menos expuesto.

Un saludo.

54
Está correcto tal cuál lo has hecho.

Si queremos saber si la cocina de una Casa es independiente o no, le pediremos al objeto Casa que nos retorne su objeto CocinaCasa y a este objeto retornado le pediremos que nos retorne el boolean que indica si la cocina es independiente.

Por tanto, la clase Casa no necesita tener su propio método para indicar como es la cocina, basta con el que ya viene incluido en su atributo CocinaCasa

55
Comunidad / Re: Presentación
« en: 28 de Mayo 2023, 21:21 »
Bienvenido Dapi.

Tanto si estás siguiendo algunos de los cursos de esta web, como si estás aprendiendo por otros medios, tienes el foro a tu disposición para preguntar y compartir lo que quieras.

Saludos.

56
Hola Magore.

La utilidad es proporcionar al programador opciones y posibilidades, y el ya luego las usará como le convenga.

Tú ahora estás viendo ejemplos básicos y sencillos como crear un Empleado, un Alumno, un Profesor, una Asignatura.... son entidades sencillas de modelar que podrán tener más o menos atributos, pero en cualquier son ideas simples.

Pero luego irás viendo que es posible crear clases tan complejas como el programador quiera y pueda..., y poder disponer de múltiples constructores agiliza mucho la creación de objetos y reduce el código necesario.

Veamos un ejemplo concreto.
Vamos a la documentación de la API de Java y fijémonos en una clase, por ejemplo la clase JLabel

Un JLabel, es una "etiqueta" que se usa en la construcción de aplicaciones con interfaz gráfica.
Permite poner en pantalla un texto, o también una imagen a modo de icono.

A priori, parece un elemento sencillo, pero si miramos su documentación veremos que tiene hasta 6 constructores distintos:


Los constructores:
  • Sin argumentos. Crea una etiqueta vacía que luego habrá que añadirle elementos con los setters si queremos que tenga alguna utilidad.
  • Objeto de tipo Icon. Recibe la imagen que ha de mostrar en pantalla
  • Objeto de tipo Icon y un int. Además de la imagen, recibe un entero que indica como ha de alinearse en su eje horizontal(izquierda, centro o derecha)
  • Objeto de tipo String. Recibe una cadena con el texto que ha de mostrar en pantalla.
  • Objeto de tipo String, un tipo Icon y un int. Recibe un texto y una imagen para mostrar en pantalla, además de un entero indicando su alineación horizontal
  • Objeto de tipo String y un int. Recibe el texto a mostrar y el entero que indica como debe alinearse horizontalmente.

Sí, todo esto podría hacerse con un único constructor sin argumentos y luego usar getters para establecer todo lo demás.

Pero es que gracias a esos constructores, en lugar de usar dos o tres líneas de código para construir un JLabel, podemos hacerlo solo con una línea de código.

Y dirás, bueno, tampoco es tanto ahorro...
Pero es que una interfaz gráfica no tiene solamente un JLabel..., puede tener diez, veinte, cincuenta...o muchas más etiquetas.
Mira esta captura, prácticamente cada texto en pantalla es una etiqueta, unas con imagen, otras solo texto, algunas centradas, otras alineadas a la izquierda...


Todas son etiquetas, pero aún siendo de la misma clase, cada una es distinta de la otra y requieren construirse de formas distintas.

Y no es lo mismo escribir "solo" 50 líneas de código para crear 50 etiquetas, que tener que escribir 150 porque tras cada constructor hay que llamar además a dos o tres getters según lo que necesite cada etiqueta.


Por eso disponer de distintos constructores, donde cada uno se adapta a las necesidades de cada objeto concreto, resulta muy útil.

60
Cuando al método de una clase le ponemos parámetros de entrada, es porque esperamos que esos parámetros provengan desde el "exterior", es decir, no son datos que existan dentro de esta clase y tenemos que recibirlos desde fuera.

Pero en este caso, esos datos existen dentro de esta clase.
Queremos comprobar el grosor de "esta Rueda", así que podemos actuar directamente con sus atributos de clase sin tener que recibir ningún parámetro de entrada.

Sería distinto si quisiéramos comprobar el grosor de "otra Rueda" distinta a "esta Rueda". Para ello, "esta Rueda" sí tendría que recibir parámetros de entrada, ya que no tiene acceso a los atributos de "otras Ruedas" y por tanto se los tendrían que proporcionar.


Si escribiéramos un código con tu Rueda, ya notarías que algo chirría.
Mira, creamos una Rueda:

Código: [Seleccionar]
Rueda miRueda = new Rueda();
miRueda.setTipo("Mojado");
miRueda.setMarca("Dunlop");
miRueda.setDiametro(0.9);
miRueda.setGrosor(0.6);

Ahora queremos comprobar las dimensiones que le hemos dado.
Pues si usamos tu método que pide parámetros de entrada, resulta que tenemos que indicarle otra vez el grosor y el diámetro:
Código: [Seleccionar]
miRueda.comprobarDimensiones(0.9, 0.6);
¿Ves? No tiene mucho sentido. El objeto miRueda ya contiene en su interior los valores de esos datos, ¿por qué pedirlos otra vez como parámetro de entrada?

Por eso este método no necesita recibir nada externo, ha de operar con los atributos internos a los cuáles puede acceder sin que le tengan que llegar como parámetros de entrada.
Código: [Seleccionar]
miRueda.comprobarDimensiones();
Espero haberme explicado bien.
Un saludo



Páginas: 1 2 [3] 4 5 6 7 8 ... 50

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".