Autor Tema: Java tipo estático/dinámico diferencia tiempo compilación y ejecución (CU00690B)  (Leído 2616 veces)

edioswaldo

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 10
    • Ver Perfil
Estimados, aqui mi respuesta al ejercicio CU00690B para su verificación.

Citar
Supongamos la superclase Vehiculo que representa a cualquier tipo de vehículo y la subclase Taxi que representa a un tipo de vehículo concreto.
a) ¿Un objeto de tipo estático declarado Taxi puede contener a un objeto Vehiculo en tiempo de ejecución?
b) ¿Un objeto de tipo estático declarado Vehiculo puede contener a un objeto Taxi en tiempo de ejecución?
c) Escribe el código de una clase Vehiculo con los atributos matricula (String) y numeroDeRuedas (int), constructor, métodos getters y setters y método toString() para mostrar la información de un vehículo.
d) Escribe el código de una clase Taxi que herede de vehículo y que además de los atributos de Vehiculo lleve un atributo adicional nombreDelConductor (String) y numeroDePlazas (int), constructor, métodos getters y setters y método toString() para mostrar la información de un Taxi.
e) Escribe el código de una clase test con el método main que cree un objeto cuyo tipo es Vehiculo, instanciado como Taxi. Establece valores para sus atributos y usa el método toString().
¿Qué método toString() resulta de aplicación, el propio de la clase Vehiculo o el propio de la clase Taxi?
¿Por qué?


 Respuestas

Citar
a) ¿Un objeto de tipo estático declarado Taxi puede contener a un objeto Vehiculo en tiempo de ejecución?

R. En teoría Si, pero en la práctica No me funcionó, me dió error  en ejecución ""vehiculo cannot be cast to taxi" revisen mas adelante mi código y sabran porque les dije.

Código: [Seleccionar]
Vehiculo carro2=new Vehiculo() ;
        Taxi taxi2= new Taxi("ABC-222",4,"Edi2",4);
        taxi2= (Taxi)carro2;

Citar
b) ¿Un objeto de tipo estático declarado Vehiculo puede contener a un objeto Taxi en tiempo de ejecución?

R. Si es posíble, al menos a mi si me funcionó en el ejercicio.

Clase Vehiculo
Código: [Seleccionar]
public class Vehiculo{
    private String matricula;
    private int numeroDeRuedas;
    public Vehiculo(){
        matricula="";
        numeroDeRuedas=0;
    }

    public Vehiculo(String matricula,int numeroDeRuedas){
        this.matricula=matricula;
        this.numeroDeRuedas=numeroDeRuedas;
    }
    public void setMatricula(String matricula){this.matricula=matricula;}
    public void setNumeroDeRuedas(int numeroDeRuedas){this.numeroDeRuedas=numeroDeRuedas;}
    public String getMatricula(){ return matricula;}
    public int getNumeroDeRuedas(){return numeroDeRuedas;}
    //método para mostrar informacion toString sobrecargado.
    public String toString(){
        return "La matricula del vehiculo es: "+getMatricula()+". El #deRuedas es: "+getNumeroDeRuedas()+ ". ";
    }//cierre del método
}//cierre de la clase


Clase Taxi

Código: [Seleccionar]
public class Taxi extends Vehiculo {
    //Atributos
    private String nombreDelConductor;
    private int numeroDePlazas;
    //Constructor general
    public Taxi(){
        super();
        nombreDelConductor="";
        numeroDePlazas=0;
    }
    //Constructor
    public Taxi(String matricula, int numeroDeRuedas, String nombreDelConductor,int numeroDePlazas){
        super(matricula,numeroDeRuedas);
        this.nombreDelConductor=nombreDelConductor;
        this.numeroDePlazas=numeroDePlazas;
    }
    //Métodos SETTERS
    public void setNombreDelConductor(String nombreDelConductor){this.nombreDelConductor=nombreDelConductor;}
    public void setNumeroDePlazas(int numeroDePlazas){this.numeroDePlazas=numeroDePlazas;}
    //Métodos GETTERS
    public String getNombreDelConductor(){return nombreDelConductor;}
    public int getNumeroDePlazas(){return numeroDePlazas;}
    //Método sobrecargado de la clase Padre Vehiculo, se lo sobrecarga.
    public String toString(){
        return super.toString()+ " El nombre del conductor es: "+getNombreDelConductor()+". El # de plazas es: "+getNumeroDePlazas()+". ";
    }//cierre del método

}//cierre de la clase


Clase Test

Código: [Seleccionar]
public class TestVehiculo{
    public static void main( String []args){
        System.out.print("\f ");
        Vehiculo carro1;//defino objeto tipo Vehiculo
        carro1=new Taxi("QWE-111",6,"Edi1",5);//instancio como Taxi
        System.out.println("Carro 1= "+carro1.toString() );
       
        // aplico CASTING pero no funciona, sale error de ejecución "vehiculo cannot be cast to taxi"
        /*
        Vehiculo carro2=new Vehiculo() ;
        Taxi taxi2= new Taxi("ABC-222",4,"Edi2",4);
        taxi2= (Taxi)carro2;     
        System.out.println("Carro 2= "+taxi2.toString());
        */
        Vehiculo carro3=new Vehiculo("ninguno",0) ;
        Taxi taxi3= new Taxi("RTY-333",8,"Edi3",8);
        carro3=taxi3;     
        System.out.println("Carro 3= "+carro3.toString() );

    }//cierre del main

}//cierre de la clase


Citar
¿Qué método toString() resulta de aplicación, el propio de la clase Vehiculo o el propio de la clase Taxi?
¿Por qué?

R. Revise ejecutando paso a paso poniendo algunos puntos de interrupciones, y en el ejercicio utilizo el método de la subclase.

Otra cosa cuando intente colocar en el método sobrecargado en la subclase Taxi de esta forma

 
Código: [Seleccionar]
public String toString(){
super();
        return toString()+ " El nombre del conductor es: "+getNombreDelConductor()+". El # de plazas es: "+getNumeroDePlazas()+". ";
    }


Ya que habia leido en el foro que al llamar un método sobrecargado que fue definido en la superclase con misma signatura, bastaba con usar solo super(); para invocar dicho método de la clase padre, pero No me funcionó me dió error de compilado "call to super must be first statement in constructor " por eso que debi usar para invocar al método "super.toString()", revisen mi código que esta en la clase Taxi para que comprendan, porque ya hice la misma consulta en otro post a alguien que le dió el mismo error pero sigue sin respuesta.

Gracias por revisar, saludos.
« Última modificación: 07 de Octubre 2015, 13:12 por César Krall »

RaGa

  • Moderador Global
  • Intermedio
  • *******
  • APR2.COM
  • Mensajes: 234
    • Ver Perfil
Hola edioswaldo:

Estuve revisando tus respuestas y veo todas muy bien salvo en aquellas dos que marcas dudas ("a" y "e"). Vayamos a ellas.

Respecto de la pregunta a)...
En la jerarquía de herencias que se plantea: todo objeto Taxi es siempre un objeto Vehiculo. Sin embargo su recíproca no se cumple: no todo Vehiculo es siempre un Taxi.
Este parece ser el problema en este punto.

Veamos, en la línea:

       
Código: [Seleccionar]
taxi2= (Taxi)carro2;

en tiempo de compilación no se marca ningún error ya que el compilador "confía" que llegado este momento de tener que hacer esta asignación, carro2 que es un Vehiculo, pueda llegar a contener efectivamente un Taxi como el casting lo pide.
Sin embargo, en tiempo de ejecución eso no sucede en este ejercicio.
carro2 no es un Taxi y estamos queriendo forzar a que lo sea. Estamos queriendo forzar que carro2 que tiene los atributos y métodos de Vehiculo tenga además "de la nada" dos atributos más y 4 métodos más (que corresponden a los de Taxi). Eso sería forzar a que se convierta en algo que no es, y nos da (logicamente) ese error en tiempo de ejecución.

Veamos ahora qué sucedería con este otro ejemplo:

       
Código: [Seleccionar]
Vehiculo carro4=new Taxi("ABC-999",4,"Edi7",4); ;
        Taxi taxi4= new Taxi("ABC-222",4,"Edi2",4);
        taxi4= (Taxi) carro4;     
        System.out.println("Carro 4= "+carro4.toString());

Aquí carro4 es tipo Vehiculo. Es decir: ese objeto tipo Vehiculo ahora EFECTIVAMENTE contiene un objeto tipo Taxi, por lo tanto en la asignación en tiempo de ejecución:

         
Código: [Seleccionar]
taxi4= (Taxi) carro4;    

no habrá ningún problema.

Insisto en lo siguiente: "Todo objeto Taxi es siempre un objeto Vehiculo. Sin embargo su recíproca no se cumple: no todo Vehiculo es siempre un Taxi."

Te planteo lo siguiente:
Supongamos que la clase Vehiculo hubiera tenido además de la clase hija Taxi, la clase hija AvionDeCarga.

Código: [Seleccionar]
        Vehiculo carro4=new new AvionDeCarga("ABC-222",4,"piloto 34","fuselejae 2K4", "container");
        Taxi taxi4= new Taxi("ABC-222",4,"Edi2",4);
        taxi4= (Taxi) carro4;     
        System.out.println("Carro 4= "+taxi4.toString());

aquí es más avidente y lógico que en tiempo de ejecución se marque con un error esta  incompatibilidad, ya que por mas casting que haga no puedo transformar un avion de carga (que es lo que realmente contiene el objeto tipo Vehiculo llamado carro4) en un objeto tipo Taxi que es lo que me pide el casting.

Respecto de la pregunta e)...
super() se utiliza en un constructor de una subclase para llamar al constructor de su super clase.
En este método sobreescrito de una subclase, si quieres hacer una llamada al método de su superclase, debes invocarlo de esa manera: super.toString()

 

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".