2012-04-10 4 views
1

私はスーパータイプ(シェイプ)と2つの子供(スクエア、サークルのような)を持っているとしましょう。スーパータイプから子へキャストバック

また
Shape shape = someObject.getShape(); 

if (shape instanceof Square){ 
    shape = (Square) shape; 
    // do this 
} else if (shape instanceof Circle) { 
    shape = (Circle) shape; 
    // do that 
} 

、正しいOO原理を思われないのインスタンスを取得しているので、それを行う別の方法があります:

私はこのような何かをしようとしていますか?乾杯。

編集。私はそれらのメソッドを呼び出すつもりはないので、それらを特定のサブタイプを必要とするいくつかのメソッドに渡したいと思います。

edit2基本的に私はそれに両方のタイプのサブタイプを保持できるようにShapeタイプのコレクションを持っています。しかし、ある時点で処理する場合、サブクラスを引数として取るメソッドに渡すことができます。引数としてスーパータイプを簡単に使用できますが、サブタイプ固有のデータを扱うので、安全ではありません。

+1

'Square square;のような新しいインスタンスを作成する必要があるかもしれません。 if(正方形の形状インスタンス){正方形=(正方形)形状; // do this} ' – twain249

+2

より良いオブジェクト指向の原則は、両方の共通のスーパータイプに共有抽象メソッドを持たせることです。次に、実際の形状が何であっても、スーパータイプ宣言を使用してクラス固有のメソッドを呼び出すことができます – ControlAltDel

+0

問題は、このメソッドを呼び出すのではなく、このオブジェクトをサブタイプを必要とする別のメソッドに渡すことです。 –

答えて

6

次の例のように、適切に変数を宣言する必要があります:あなたはJavaでの参照を宣言したら

if (shape instanceof Square){ 
    Square square = (Square) shape; 
    // do this with square 
} else if (shape instanceof Circle) { 
    Circle circle = (Circle) shape; 
    // do that with circle 
} 
+0

同じ変数を保持するために、まあ、それ自体です。おそらくそれを行うことはできません:/ –

+0

Javaでは、実際の代入オブジェクトではなく、変数型に宣言されたメソッドを呼び出すことができます。いくつかのメソッドがオーバーライドされると、新しいバージョンが呼び出されます。 – MByD

+0

ええ、私はそれを知っている、私はちょうどそれらの特定のクラスの種類の特定の引数を持つ異なるメソッドにサブタイプを渡す必要があります... –

1

あなたは彼のタイプを変更することはできません。あなたがするとき:

Shape shape = someObject.getShape(); 

「可変シェイプへのシェイプへの参照の保存」と言っています。あなたがそのタイプを変更することはできませんので、それはあなたがその形状(左側)と言っているので、

shape = (Square) shape; 

をやっては意味を持たないことは関係なく、割り当ての右側にあるもの、形ではありません。

覚えておいてください:参照の型を宣言したら、それを変更することはできません。

1

私は本当にあなたがここで達成しようとしているのか理解していないが、あなたが最初に実際のクラスをチェックすると、そのキャスト問題はありませんオフコースあなたが

shape.getClass().isAssignableFrom(Square.class) ? processSquare((Square)shape) : processCircle((Circle)shape) 

の形で例を異なる場合があります。

編集あなたの形状クラスの種類は変更されません:

Shape[] shapes = new Shape[]{new Circle()} 

あなたがCircle.classタイプを取得しますshapes[0].getClass()呼び出すときに、あなたの図形のコレクションをループしているよう。したがって、あなたの形状コレクションを繰り返し、どのタイプの特定のコレクションを呼び出すかを決める必要があるときには、例えば、shape.getClass().isAssignableFrom(Circle.class)に電話してケースを切り替えることができます。次に、型をキャストして、必要なメソッドを呼び出すことができます。あなたのシェイプオブジェクトを異なるコレクションに保持する必要はありません。

+0

ルックエディット2の場合に役立ちます:) –

+0

あなたのアプリケーションの設計はちょっと混乱していると思います。しかし、それとは別に、それが表示されているように、インスタンスのactuelクラス型は、それを格納しているスーパータイプ変数にもかかわらず変更されません。私の投稿を編集してそのことを明確にしてください –

+0

私は自分の形のオブジェクトを別のコレクションに持っていません。 :P私は1つのArrayList を持っています。私はメソッドを持って、cutSquareInHalf(Square sq)と言うことができます。だから私がコレクションからシェイプオブジェクトを取得するとき、私はそれが実際に正方形かどうかを知る必要があるので、それをキャストしてそのメソッドに渡すことができます。 –

関連する問題