#java #exception #casting #subclass #superclass
#java #исключение #Кастинг #подкласс #суперкласс
Вопрос:
Я получаю ошибку в названии, когда пытаюсь использовать метод getInfoDerivada()
из Desguace
:
Исключение в потоке «main» java.lang.ClassCastException: es.unex.cum.mdp.sesion2.Vehiculo не может быть приведен к es.unex.cum.mdp.sesion2.Moto в es.unex.cum.mdp.sesion2.Desguace.getInfoDerivada(Desguace.java:93) в es.unex.cum.mdp.sesion2.Main.main(Main.java:21)
И я не знаю, как привести подкласс 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);
}
}
Описание класса
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;
}
}
Класс Vehiculo
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;
}
}
Класс Moto
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 "]";
}
}
Комментарии:
1. используйте
instanceof
вместо проверки, равны ли классы, другими словамиvehiculos[pos].getClass() == Coche.class
, должно бытьvehiculos[pos] instanceof Coche.class
2. Он по-прежнему возвращает null, и я не знаю почему, похоже, что if никогда не бывает true .
Ответ №1:
Вы можете преобразовать a Moto
в a Vehiculo
без необходимости что-либо проверять и необходимости приводить его как к Moto
подклассу of , Vehiculo
но если вы хотите сделать обратное, вам нужно сначала проверить, является ли ваш экземпляр Vehiculo
экземпляром Moto
using 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
, когда вы доходите до последнего случая, вы приводите его к a 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
provided вместо создания нового экземпляра 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();
}
Комментарии:
1. То, что я предлагаю в конце, — это подход OO, так что это путь сюда, поскольку ваш учитель должен знать, что Java — это язык программирования OO
2. Большое вам спасибо, хотя я не мог напрямую назначить экземпляр массиву. Извините за мои ошибки при публикации / редактировании, впервые здесь.