2016-11-11 6 views
2

これを明確にしようとしているので、型キャストを完全に理解しています。本当に遅いペースで約2ヶ月間私は自己学習Javaを行ってきたので、間違っているもので私を修正してください。型キャスト/ Javaのダウンキャスト

たとえば、私はSubObjectというクラスを作成しました。私は、直接的に明示的なスーパークラスを持たないすべてのクラスは、Objectクラスのサブクラスであると認識しています。

Object obj1 = new SubObject(); 
    SubObject subObj1 = (SubObject) obj1; 
    System.out.println(subObj1); //prints out com.examplePackage.SubObject1234e1234; 

だから私は成功したその派生クラス(サブオブジェクト)への基底クラス(オブジェクト)の参照をdowncastedています。しかし... ClassCastExceptionがエラーの

Object obj2 = new Object(); 
SubObject subObj2 = (SubObject) obj2;//this throws the ClassCastException error. 

私の理解では、コードが、それはインスタンスではありませんそのサブクラスにオブジェクトをキャストしようとしたことを示すために、コンパイル時にそれをキャッチするためのRuntimeExceptionを継承したということです。 subObj2はSubObjectのインスタンスではなくObjectであるため、互換性がありません。

私は2つの質問があります: 1.私の理解に何らかの欠陥がありますか? 2.ダウンキャスティングは実際にどのような状況で使用されていますか?みんな助けてくれてありがとう。

答えて

1

RuntimeExceptionの関連性は、'unchecked'です。したがって、開発者はそれに対処することを強いられません。通常の方法は、(ifステートメントを使用し、instanceOfのようなものを使用して)キャストを許可する前にキャストが許可されているかどうかを確認することです。異例で、上級開発者の心の中で警鐘を鳴らし、すなわち何か -

if(subObj2 instanceof SubObject) { 
    SubObject s2 = (SubObject) obj2; 
    ... 
} 

ので、しかし、これは「コードのにおい」とみなされます。一般に、多態性によってこのようなことを達成する必要がありますが、必ずしもそうではありません。ほとんどのタイプのプログラムでは、ほとんどの場合、型キャストは必要ありません。

しかし、あなたの考えは概ね正しいです。

0

ダウンキャスティングが発生する可能性がある状況は、工場設計パターンのコンテキストにあります。この設計パターンでは、複数の子クラスの実装の詳細は、親クラスを使用するだけで抽象化できます。

は、以下の例を考えてみます

import java.util.ArrayList; 

public class Factory { 

private ArrayList<Product> products = new ArrayList<Product>(); 

public static void main(String[] args){ 
    Factory factory = new Factory(); 

    factory.addProduct(new Ball("1")); 
    factory.addProduct(new ToyCar("2")); 
    factory.addProduct(new Dice("3")); 

    Product popProduct = factory.popProduct(); 

    Ball downcastBall = (Ball)popProduct; 

    System.out.println(downcastBall.getId()); 
} 

public void addProduct(Product prodIn){ 
    products.add(prodIn); 
} 

public Product popProduct(){ 
    Product returnProd = products.get(0); 
    products.remove(0); 
    return returnProd; 
} 
} 

にクラスのボールを、ToyCarとサイコロのすべては、Productクラスを拡張し、それののgetId()メソッドを実装し、その3人の子供はすべて単なる製品として扱うことができます。これを多型といいます。

私はあなたの周りに遊ぶことができるようにコードの残りの部分を投稿します。

ボールクラス:

public class Ball extends Product{ 

public Ball(String id) { 
    super(id); 
} 

public String getId(){ 
    return "ball!"; 
} 
} 

ToyCarクラス:

public class ToyCar extends Product{ 

private String ToyCarId; 

public ToyCar(String id) { 
    super(id); 

} 

public String getId(){ 
    return this.ToyCarId; 
} 
} 

ダイスクラス:

public class Dice extends Product{ 

private String diceId; 

public Dice(String id) { 
    super(id); 

} 

public String getId(){ 
    return this.diceId; 
} 
} 

そして最後に、Productクラス:

public class Product { 

private String id; 

public Product(String id){ 
    this.id = id; 
} 

public String getId(){ 
    return this.id; 
} 
}