2011-10-26 7 views
1

私はオブジェクトが実装する親インターフェイスと子インターフェイスを持っています。特定のVehicleEntityオブジェクトをTruckというようにして、自分自身をHashMapに追加するために、子インターフェイスを作成しました。Carです。 TruckはVehicleManagerのaddToCar()メソッドを呼び出して、TruckオブジェクトをCarのhashMapに追加します。私が持っている問題はCarEntity ce = ve;です。 NetBeansはCarEntityにveをキャストするよう指示していますが、私はしたくありません。コードの行は有効ではないはずです(forループが見ているオブジェクトがCarオブジェクトであると仮定します)。これをどうすれば解決できますか?子オブジェクトに親オブジェクトを割り当てるJavaでキャストしないで

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 
     } 
    } 
} 
+0

'reportToCar'メソッドはどのクラスに属していますか? –

+0

class VehicleManager – Dan

+0

ここにはさらに問題があります。 'addToCar'では、HashMapで' add'を呼び出します。そのような方法はありません。 'put(String c、Something s)'を使う必要があります。それは何ですか? –

答えて

5

実際、これはまったく有効ではありません。キャスティングすることなく特定のものから一般のものへ移動できますが、もう一度戻ることはできません。たとえば、ArrayListをList変数に格納することはできますが、Listを取得してキャストせずにArrayList変数に格納することはできません。同じように、あなたは車を取って明示的にキャスティングすることなく車であると言うことはできません。

この場合、車両が車であることを知っているため、明示的に車にキャストします。

+0

を参照してください。それは私が最初に考えたことですが、ちょうど確認が必要でした。ありがとう! – Dan

0

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"); 

    } 

} 

私はVehicleEntityを拡張Tと方法reportをパラメータ化しました。そのタイプのものが返されますT。これをメソッドtest()に使用する場合は、Carが必要です。ここでいくつかの型推論が行われ、タイプCarのメソッドreportが自動的に呼び出されます。指定されたidを持つマップ内のVehicleEntityCarではない場合、そのコンテキストでthetメソッドを呼び出すときにCarにキャストしようとしているので、ClassCastExceptionが発生します。

+0

私の問題は鋳造に関するものでした。私はキャストしたくないが、@Micahはそれができないと述べた。 – Dan

+0

@ダン時々あなたはキャストする必要があります。しかし、あなたのデザインが達成しようとしているものが何であるかは分かりません。異なるアプローチが異なる結果を生み出すかもしれません。キャストなし。あなたの現在の構造だけではありません。タイプごとに別々のVehicleManagerを持つことができれば(ジェネリックで)避けることができますが、そうでないので、私の提案はあなたが作るVehicleEntityの各サブタイプに対して別個のメソッドを持つことを避けることができます。心に留めておくべきこと。 –

関連する問題