Исключение java.lang.classCastException при приведении подкласса из Суперкласса

2

Я получаю ошибку в заголовке, когда пытаюсь использовать метод getInfoDerivada() из Desguace:

Исключение в потоке "main" java.lang.ClassCastException: es.unex.cum.mdp.sesion2.Vehiculo нельзя отнести на es.unex.cum.mdp.sesion2.Moto at es.unex.cum.mdp.sesion2.Desguace.getInfoDerivada(Desguace.java:93) на es.unex.cum.mdp.sesion2.Main.main(Main.java:21)

И я не знаю, как getPotencia() подкласс Moto к использованию своего метода getPotencia() из суперкласса Vehiculo.

благодаря

package es.unex.cum.mdp.sesion2;

public class Main {

    public static void main(String[] args) {

        Persona p = new Persona();
        Vehiculo v = new Coche("Renault","Asd",p,1234,"azul");
        Vehiculo v1 = new Moto("a","b",p,2345,25);

        if(v.getClass().equals(Coche.class))
            System.out.println("holi 1.0");

        Desguace d = new Desguace("pepe",2);

        if(d.addVehiculo(v))
            System.out.println("ok");
        if(d.addVehiculo(v1))
            System.out.println("ok");

        String a = d.getInfoDerivada(1);
        String b = v1.toString();
        System.out.println(b);

        System.out.println(a);

    }

}

Класс Desguace

package es.unex.cum.mdp.sesion2;

import java.util.Arrays;

public class Desguace {
    protected String nombre;
    protected Vehiculo [] vehiculos;
    protected Integer cont;


    public Desguace() {
        nombre = "";
        vehiculos = new Vehiculo[0];
        cont = 0;
    }

    public Desguace(String nombre, int cant) {
        this.nombre = nombre;
        vehiculos = new Vehiculo[cant];
        cont = 0;
    }

    public boolean addVehiculo (Vehiculo v){
        for(int i = 0; i < cont; i++)
            if(vehiculos[i].getBastidor() == v.getBastidor())
                return false;
        if(cont<vehiculos.length){
            vehiculos[cont] = new Vehiculo(v);
            cont = cont + 1;
            return true;
        }
        else
            return false;
    }

    public Vehiculo getVehiculoBastidor(Integer bastidor){
        if(bastidor < 0)
            return null;
        for(int i = 0; i < cont; i++){
            if(vehiculos[i].getBastidor()==bastidor)
                return vehiculos[i];
        }
        return null;
    }

    public boolean addPiezaVehiculo(Pieza p, Integer bastidor){
        if(bastidor < 0)
            return false;
        for(int i = 0; i < cont; i++){
            if(vehiculos[i].getBastidor() == bastidor){
                for(int j = 0; j < vehiculos[i].getCont(); j++){
                    if(vehiculos[i].getPiezaV(j).equals(p)){
                        vehiculos[i].getPiezaV(j).setContador(vehiculos[i].getPiezaV(j).getContador() + p.getContador());
                        return true;}
                    else{
                        if(vehiculos[i].getCont() < 3){
                            vehiculos[i].addPiezaV(p);
                            vehiculos[i].setCont(vehiculos[i].getCont()+1);
                        }
                        else
                            return false;
                    }
                }

            }
        }
        return false;
    }

    public Vehiculo mayorStock(){
        int aux = 0;
        if(vehiculos[aux] == null)
            return null;
        for(int i = 1; i < cont; i++){
            if(vehiculos[aux].getCont() < vehiculos[i].getCont())
                aux = i;
        }
        return vehiculos[aux];  
    }

    public String getInfoDerivada(int pos){
        if(pos < 0 || pos >= cont){
            return null;}
        if(vehiculos[pos].getClass() == Coche.class){
            return ((Coche)vehiculos[pos]).getColor();
        }
        if(vehiculos[pos].getClass() == Moto.class){
            return String.valueOf(((Moto)vehiculos[pos]).getPotencia());
        }
        if(vehiculos[pos].getClass() == Camion.class){
            return String.valueOf(((Camion)vehiculos[pos]).getTonelaje());
        }
            return String.valueOf(((Moto)vehiculos[pos]).getPotencia());
    }

    public String getNombre() {
        return nombre;
    }
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
    public Integer getCont() {
        return cont;
    }
    public void setCont(Integer cont) {
        this.cont = cont;
    }
    public Vehiculo[] getVehiculos() {
        return vehiculos;
    }

    @Override
    public String toString() {
        return "Desguace [nombre=" + nombre + "]";
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Desguace other = (Desguace) obj;
        if (cont == null) {
            if (other.cont != null)
                return false;
        } else if (!cont.equals(other.cont))
            return false;
        if (nombre == null) {
            if (other.nombre != null)
                return false;
        } else if (!nombre.equals(other.nombre))
            return false;
        if (!Arrays.equals(vehiculos, other.vehiculos))
            return false;
        return true;
    }



}

Класс транспорта

package es.unex.cum.mdp.sesion2;

public class Vehiculo {
    protected String marca;
    protected String modelo;
    protected Persona propietario;
    protected Pieza[] piezas;
    protected Integer bastidor;
    protected Integer cont;

    public Vehiculo() {
        marca = "";
        modelo = "";
        propietario = new Persona();
        bastidor = 0;
        piezas=new Pieza[3];
        for(int i = 0; i < piezas.length; i++)
            piezas[i] = new Pieza();
        cont=0;
    }

    public Vehiculo(String marca, String modelo, Persona p, Integer bastidor) {
        this.marca = marca;
        this.modelo = modelo;
        this.bastidor = bastidor;
        propietario = new Persona(p.getNombre(),p.getDni(),p.getEdad());
        piezas=new Pieza[3];
        for(int i = 0; i < piezas.length; i++)
            piezas[i] = new Pieza();
        cont = 0;
    }

    public Vehiculo(Vehiculo p) {
        this(p.getMarca(),p.getModelo(),p.propietario, p.getBastidor());
    }

    public boolean addPiezaV(Pieza p) {
        for(int i = 0; i < cont; i++){
            if(piezas[i].equals(p))
                piezas[i].setContador(piezas[i].getContador()+p.getContador());
        }
        piezas[cont].setId(p.getId());
        piezas[cont].setNombre(p.getNombre());
        piezas[cont].setContador(p.getContador());
        cont = cont + 1;
        return true;

    }

    public Pieza getPiezaV(int pos) {
        if(pos >= piezas.length || pos < 0)
            return null;
        else
            return piezas[pos];


    }
    //getter y setter

    public String getMarca() {
        return marca;
    }

    public void setMarca(String marca) {
        this.marca = marca;
    }

    public String getModelo() {
        return modelo;
    }

    public void setModelo(String modelo) {
        this.modelo = modelo;
    }

    public Integer getBastidor() {
        return bastidor;
    }

    public void setBastidor(Integer bastidor) {
        this.bastidor = bastidor;
    }

    public Integer getCont(){
        return cont;
    }

    public void setCont(Integer cont){
        this.cont = cont;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Vehiculo other = (Vehiculo) obj;
        if (bastidor == null) {
            if (other.bastidor != null)
                return false;
        } else if (!bastidor.equals(other.bastidor))
            return false;
        if (cont == null) {
            if (other.cont != null)
                return false;
        } else if (!cont.equals(other.cont))
            return false;
        if (marca == null) {
            if (other.marca != null)
                return false;
        } else if (!marca.equals(other.marca))
            return false;
        if (modelo == null) {
            if (other.modelo != null)
                return false;
        } else if (!modelo.equals(other.modelo))
            return false;
        if (propietario == null) {
            if (other.propietario != null)
                return false;
        } else if (!propietario.equals(other.propietario))
            return false;
        return true;
    }

}

Класс Мото

package es.unex.cum.mdp.sesion2;

public class Moto extends Vehiculo {
    protected Integer potencia;

    public Moto(){
        super();
        potencia = 0;
    }

    public Moto(String marca, String modelo, Persona p, Integer bastidor, Integer potencia){
        super(marca,modelo,p,bastidor);
        this.potencia = potencia;
    }

    public Integer getPotencia() {
        return potencia;
    }

    public void setPotencia(Integer potencia) {
        this.potencia = potencia;
    }

    @Override
    public String toString() {
        return "Moto[marca=" + marca + ", modelo=" + modelo + ", bastidor=" + bastidor + ", potencia=" + potencia +"]";
    }

}
  • 0
    используйте instanceof вместо того, чтобы проверять, равны ли классы, другими словами vehiculos[pos].getClass() == Coche.class должен быть vehiculos[pos] instanceof Coche.class
  • 0
    Это все еще возвращает ноль, и я не знаю почему, кажется, что если это никогда не правда.
Теги:
exception
casting
superclass
subclass

1 ответ

0
Лучший ответ

Вы можете преобразовать Moto в транспортное Vehiculo без необходимости проверять что-либо и необходимость отбрасывать его, поскольку Moto является подклассом Vehiculo но если вы хотите сделать обратное, вам нужно сначала проверить, если ваш экземпляр Vehiculo является экземпляром Moto используя instanceof потому что экземпляр Vehiculo не нужен, экземпляр Moto который является причиной, вызывает вашу проблему здесь, когда вы получаете ClassCastException. Хуже того, в соответствии с вашим сообщением об ошибке вы пытаетесь привести экземпляр Vehiculo к экземпляру Moto который просто невозможен.

if (vehiculos[pos] instanceof Moto) {
    // Here we can safety cast to a moto
    Moto moto = (Moto) vehiculos[pos];
    ...
}

Ваша проблема заключается в методе getInfoDerivada когда вы достигаете последнего случая, вы getInfoDerivada его на Moto который не может быть так, как мы уже знаем, что это не экземпляр Moto.

Ваш код должен быть примерно таким:

public String getInfoDerivada(int pos){
    if(pos < 0 || pos >= cont){
        return null;
    }
    if(vehiculos[pos] instanceof Coche){
        return ((Coche)vehiculos[pos]).getColor();
    } else if(vehiculos[pos] instanceof Moto){
        return String.valueOf(((Moto)vehiculos[pos]).getPotencia());
    } else if(vehiculos[pos] instanceof Camion){
        return String.valueOf(((Camion)vehiculos[pos]).getTonelaje());
    }
    throw new IllegalStateException(
        String.format("Unknown type: %s", vehiculos[pos].getClass().getName())
    );
}

Ваша ошибка на самом деле в addVehiculo, вы должны напрямую назначить экземпляр Vehiculo вместо создания с ним нового экземпляра Vehiculo.

public boolean addVehiculo (Vehiculo v){
    ...
    if(cont<vehiculos.length){
        vehiculos[cont] = v;// instead of new Vehiculo(v);
        ...
    }
    ...
}

Гораздо лучшим подходом было бы добавить новый метод getInfoDerivada в класс Vehiculo для которого вы предоставите реализацию по умолчанию, а затем переопределите его в подклассах, если это необходимо, ваш код будет просто:

public String getInfoDerivada(int pos){
    if(pos < 0 || pos >= cont){
        return null;
    }
    return vehiculos[pos].getInfoDerivada();
}
  • 0
    Да, но учитель хочет, чтобы я делал это таким образом.
  • 1
    В конце я предлагаю подход OO, так что это путь, по которому ваш учитель должен знать, что Java является языком OO
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню