2016-05-18 1 views
5

は、これらのクラスを持つ:スーパークラスオブジェクトの配列。それらをサブクラスとして管理する方法は?

public abstract class Furniture 

public class Chair : Furniture 

public class Table : Furniture 

public class Kitchen 
{ 
ArrayList <Furniture> furnitures; 
//other code 
public void function() 
{ 
    Furniture furniture = furnitures.get(); 
    doSomethingInKitchen(furniture); 
} 


private void doSomethingInKitchen (Chair c); 
private void doSomethingInKitchen (Table t); 

} 

私は私がサブクラス1(椅子やテーブル)としてスーパークラスの家具のオブジェクトを操作するには保証のベストプラクティスを探しています。

私は単純なキャストで試してみましたが、私が関数を呼び出すと、テーブルやチェアのものではなく、家具オブジェクトで動作します。

私が試したことのようなものです:問題はcurrentFurnitureが

Furniture currentFurniture; 

として宣言され、それが議長として認識されないことがあるかどうかは知りません

for each Furniture in Array List 
if(furniture.get() istance of Table) 
{ 
currentFurniture = (Table) furniture.get(); 
} 

else if (furniture.get() istanceof Chair) 
{ 
currentFurniture = (Chair) furniture.get(); 
} 
doSomethingInKitchen(currentFurniture) 

キャスティングにもかかわらず、またはソリューションのデザイン自体が間違っている場合は、テーブル。

+0

**多型は**メソッドが呼び出されるオブジェクトのタイプに基づいて動作します。メソッドの引数の型ではありません。 'furniture.doSomethingInTheKitchen()'でなければなりません。麻生は、Javaでエラーを尋ねるときに、疑似コードではなく、実際のJavaコードを投稿します。 –

+0

JBNizetが述べたことをちょっと補足してください:あなたの例では、あなたのオブジェクトを "使う"と仮定します。このようにして、 '(Kitchen Object).furniture.get()。use();'このようにして、コードが存在するかどうか心配することなく、上級クラスと下位クラスをコーディングすることができます。 – Bonatti

答えて

3

キャストは、共通変数に再割り当てするとすぐに失われます。

理想的には、キャストは避けて、サブクラス自体に異なるロジックを実装します。たとえば:

abstract class Furniture { 
    abstract void doSomethingInKitchen(); 
} 

class Table extends Furniture { 
    @Override 
    void doSomethingInKitchen() { 
     // Table-specific logic 
    } 
} 

class Chair extends Furniture { 
    @Override 
    void doSomethingInKitchen() { 
     // Chair-specific logic 
    } 
} 

は今、あなたはFurnitureクラスを継承しているので、あなただけの

for (Furniture furniture : furnitures) { 
    furniture.doSomethingInKitchen(); 
} 
+0

シンプルでクリアです。いい答えだ! – EagleOne

+0

ご注意ください \t 私は2つのdoSomethingInKitchen関数を書いています。その指示は、(テーブル/チェア)よりもKitchenパラメータではるかに機能するためです。最初のバージョンでは明確ではないと思うので、このコメントに基づいて質問を編集しました。 – EagleOne

2

を行い、あなたのKitchenにすることができますそれぞれchairTable

private void doSomethingInKitchen (Chair c); 
private void doSomethingInKitchen (Table t); 

ため2 methodsを実装する必要がtheresのこのような単一の方法を持つ

であり、鋳造のRaidをforloopに取得して、このメソッドにキャストを実行させることができます。

private void doSomethingInKitchen (Furniture f){ 

    if(f instanceof Table){ 
    //code for the table 
    }else{ 
    //code for the chair 
    } 

} 
+0

これは有効な答えですが、すでにリファクタリングしている場合は、代わりに多態性を使用します。 – shmosel

+0

それはうまくいくが、それは良い習慣とはみなされない。継承を使用している場合は、子どものメソッドをオーバーライドする可能性があります。 – Kaostias

+0

私はちょうど彼に、それぞれのクラスのためのメソッドを持たせることは良い方法ではないことを示したかったのです。opが 'オーバーライドメソッド'を持っていても、 'スーパークラスオブジェクト'を '反復している'ので、 'オブジェクト'を何らかの形でキャストすべきです。そうでなければ 'スーパークラス'でメソッドを実行します。 – Priyamal

関連する問題