Присвоение родительского объекта дочернему объекту без приведения в Java - PullRequest
1 голос
/ 27 октября 2011

У меня есть родительский интерфейс и дочерний интерфейс, которые будут реализованы объектами. Я создал дочерний интерфейс, потому что я хочу, чтобы конкретный объект VehicleEntity, скажем Truck, добавил себя в HashMap в Car. Truck вызовет метод addToCar() VehicleManager, который добавит объект Truck в hashMap Car. У меня есть проблема CarEntity ce = ve;. Netbeans говорит мне, чтобы я разыграл ve CarEntity, но я не хочу. Разве строка кода не должна быть действительной (при условии, что объект, на который смотрит цикл, является объектом Car)? Как я могу это исправить?

public interface VehicleEntity {
    getId();
    getSpeed();
    move();
    }

public interface CarEntity extends VehicleEntity{
    addToCar(String c);
}

public class Car implements CarEntity{
HashMap<String, VehicleEntity> cars = new HashMap<String, VehicleEntity>();

    public void addToCar(String c) {
       cars.add(c);
    }
}

public class VehicleManager {
    HashMap<String, VehicleEntity> vehicles = new HashMap<String, VehicleEntity>();

public void reportToCar(String id) {
    for (VehicleEntity ve : ve.values()) {
        if (ve.getId().equals(id)) {
            CarEntity ce = ve; // Issue here
        }
    }
}

Ответы [ 2 ]

5 голосов
/ 27 октября 2011

Действительно, это совсем не так.Вы можете перейти от конкретного к общему без приведения, но не обратно.Например, вы можете сохранить ArrayList в переменной List, но вы не можете взять List и поместить его в переменную ArrayList без приведения.Таким же образом, вы не можете взять транспортное средство и сказать, что это автомобиль без явного заброса.

Итак, в этом случае, поскольку вы знаете, что транспортное средство - это машина, явное приведение к машине.1003 *

0 голосов
/ 27 октября 2011

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

public interface VehicleEntity {

    public String getId();

    public String getSpeed();

    public void move();

}

public interface CarEntity extends VehicleEntity {

    public void addToCar(String key, CarEntity c);

}

import java.util.HashMap;

public class Car implements CarEntity{ 
HashMap<String, VehicleEntity> cars = new HashMap<String, VehicleEntity>();

    @Override
    public void addToCar(String key, CarEntity car) {
       cars.put(key, this);
    }

    @Override
    public String getId() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public String getSpeed() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void move() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

... а затем покажу вам классный трюк с использованием дженериков:

import java.util.HashMap;

public class VehicleManager {

    HashMap<String, VehicleEntity> vehicles =
        new HashMap<String, VehicleEntity>();

    public <T extends VehicleEntity> T report(String id) {
        for(VehicleEntity ve : vehicles.values()) {
            if(ve.getId().equals(id)) {
                @SuppressWarnings("unchecked")
                T ce = (T)ve;
                return ce;
            }
        }
        return null;
    }

    public void test() {

        final Car c = report("test");

    }

}

Я параметризовал метод report с расширением T VehicleEntity. Он вернет что-то такого типа T. При использовании этого в методе test() мы заявили, что нам нужен Car. Теперь будет происходить вывод некоторых типов, автоматически вызывающий метод report для типа Car. Если VehicleEntity на карте с указанным идентификатором не является Car, мы получим ClassCastException, поскольку мы пытаемся привести к Car при вызове метода thet в этом контексте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...