2016-05-18 11 views
5

होने इन कक्षाओं:superclass वस्तुओं के ऐरे। Subclass वाले के रूप में उन्हें कैसे प्रबंधित करें?

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

} 

मैं सबसे अच्छा अभ्यास है कि मुझे भरोसा दिलाते एक उपवर्ग एक (अध्यक्ष या तालिका) के रूप में सुपर क्लास फर्नीचर वस्तु में हेरफेर करने के लिए देख रहा हूँ।

मैंने एक साधारण कलाकार के साथ प्रयास किया, लेकिन जब मैं फ़ंक्शन को कॉल करता हूं तो यह फर्नीचर ऑब्जेक्ट के साथ संचालित होता है, न कि टेबल या चेयर के साथ।

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) 

मैं अगर समस्या यह है कि currentFurniture रूप

Furniture currentFurniture; 

घोषित किया जाता है और इसलिए यह अध्यक्ष के रूप में मान्यता प्राप्त नहीं किया जाएगा या नहीं पता है:

मैं क्या करने की कोशिश की कुछ की तरह है कास्टिंग के बावजूद तालिका या समाधान के डिजाइन स्वयं गलत है।

+0

पॉलिमॉर्फिज्म ऑब्जेक्ट के प्रकार के आधार पर काम करता है ** जिस पर ** विधि कहा जाता है। विधि के तर्क के प्रकार पर नहीं। यह 'furniture.do SomethingInTheKitchen()' होना चाहिए। एएसओ, जावा में त्रुटियों के बारे में पूछते समय वास्तविक जावा कोड पोस्ट करें, छद्म कोड नहीं। –

+0

जेबीबीज़ेट ने जो कहा है उस पर बस एक पूरक: आपके उदाहरण में, मान लीजिए कि आप अपनी वस्तु का "उपयोग" करते हैं। इस तरह, आप '(रसोई वस्तु) .furniture.get() का उपयोग कर सकते हैं(); इस प्रकार, यदि कोड मौजूद है तो चिंता किए बिना, आप ऊपरी और निचले वर्गों को कोड कर सकते हैं। – Bonatti

उत्तर

3

जैसे ही आप इसे सामान्य चर पर पुन: असाइन करते हैं, आपकी कास्ट खो जाती है।

for (Furniture furniture : furnitures) { 
    if (furniture instanceof Table) { 
     doSomethingInKitchen((Table)furniture); 
    } else if (furniture instanceof Chair) { 
     doSomethingInKitchen((Chair)furniture); 
    } 
} 

आदर्श रूप में, हालांकि, आप पूरी तरह से कास्टिंग से बचने और उपवर्ग पर ही भिन्न तर्क लागू करना होगा: आप प्रत्येक प्रकार संभाल की जरूरत है। उदाहरण के लिए:

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 
    } 
} 
अब में

अपने Kitchen तुम सिर्फ

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

सरल और स्पष्ट। अच्छा उत्तर! – EagleOne

+0

कृपया ध्यान दें कि \t मैंने दो doSomethingInKitchen फ़ंक्शन लिखा क्योंकि इसके निर्देश रसोई कक्षों के साथ (टेबल/चेयर) की तुलना में अधिक काम करते हैं। इस टिप्पणी के अनुसार प्रश्न संपादित किया क्योंकि मुझे लगता है कि यह पहले संस्करण में स्पष्ट नहीं था। – EagleOne

2

कर जब से तुम Furniture वर्ग थेरेस इनहेरिट कर रहे हैं प्रत्येक chair और Table

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

आप कर सकते हैं के लिए 2 methods को लागू करने की कोई जरूरत नहीं इस तरह की एक विधि है जैसे

private void doSomethingInKitchen (Furniture f); 

और आप forloop में कास्टिंग के माध्यम से प्राप्त कर सकते हैं और विधि को कास्टिंग करने दें।

private void doSomethingInKitchen (Furniture f){ 

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

} 
+0

यह एक वैध उत्तर है, लेकिन यदि आप पहले ही रिफैक्टरिंग कर रहे हैं, तो मैं इसके बजाय बहुरूपता के साथ जाऊंगा। – shmosel

+0

यह काम करने के बावजूद, यह एक अच्छा अभ्यास नहीं माना जाता है। यदि आप विरासत का उपयोग कर रहे हैं, तो बच्चों की विधियों को ओवरराइड करने की वास्तविक क्षमता का उपयोग क्यों न करें? – Kaostias

+0

मैं बस उसे दिखाना चाहता था कि, प्रत्येक वर्ग के लिए एक विधि होने का एक अच्छा अभ्यास नहीं है।भले ही ओप के पास ओवरराइडिंग विधियां हों, फिर भी उसे 'ऑब्जेक्ट' को 'ऑब्जेक्ट' पर रखा जाना चाहिए क्योंकि वह 'सुपरक्लास ऑब्जेक्ट' को फिर से चालू कर रहा है अन्यथा वह 'सुपर क्लास', – Priyamal

संबंधित मुद्दे