2012-08-03 31 views
9

मैं कर रहा हूँ एक ClassCastException जब भी मैं एक AdvancedBufferedImage (बच्चे) जो मैं अपने आप को बढ़ाया करने के लिए एक BufferedImage (पैरेंट) कास्ट करने के लिए प्रयास करते हैं, मैं ओवरराइड नहीं किया है किसी भी तरीके और मैंने कार्यान्वित सभी ठेकेदारों उन्हें संशोधितकास्टिंग माता पिता - BufferedImage वस्तु

जब भी मैं ImageIO.read() विधि का उपयोग कर फ़ाइल के बाहर एक AdvancedBufferedImage बनाने की कोशिश मैं इस अपवाद gettign कर रहा हूँ बिना।

File file = new file(path); 
AdvancedBufferedImage image = (AdvancedBufferedImage) ImageIO.read(file); 

ऐसा लगता है कि कोई समस्या नहीं होनी चाहिए, समस्या क्या हो सकती है?

उत्तर

15

इस तरह की डाउनकास्टिंग की अनुमति नहीं है।

पसंदीदा समाधान उन्नत BufferedImage का एक निर्माता बनाने के लिए होगा, BufferedImage पैरामीटर के रूप में ले जाएगा। इसके साथ आप निम्नलिखित कर सकते हैं।

File file = new file(path); 
AdvancedBufferedImage image = new AdvancedBufferedImage(ImageIO.read(file)); 

यहाँ AdvancedBufferedImage के निर्माता तय कर सकते हैं कि कैसे ठीक से एक उन्नत एक में एक BufferedImage कन्वर्ट करने के लिए ..

+0

तो आप BufferedImage के लिए AdvancedBufferedImage के रिश्ते को बदलने का सुझाव देते हैं, ऐसा नहीं है? –

+0

बिल्कुल। यह दृष्टिकोण आपको उन विधियों को प्रतिनिधि करने की अनुमति देता है जिन्हें आप स्वयं लागू नहीं करना चाहते हैं, और फिर भी अतिरिक्त कार्यक्षमता जोड़ें। आप बस मौजूदा कक्षा को लपेटेंगे। –

+6

सिर्फ एक नोटिस है कि ग्रहण में ऐसा करने के लिए एक आसान उपकरण है, उस वर्ग को बनाएं जिसमें उस वर्ग का उदाहरण है जिसे आप प्रतिनिधि बनाना चाहते हैं, सदस्य पर राइट क्लिक करें, 'प्रतिनिधि विधियां'। विशाल कक्षाओं के लिए बहुत आसान –

-1

आपका डाउनकास्ट केवल तभी सफल होगा यदि आप जिस वस्तु को डालने का प्रयास कर रहे हैं वह वास्तव में उस वर्ग का उदाहरण है जिसका आप कास्टिंग कर रहे हैं।

4

आप माता-पिता वर्ग को एक क्लाइंट क्लास में नहीं डाल सकते हैं जब तक कि माता-पिता वर्ग के संदर्भ में बच्चे वर्ग या इसके व्युत्पन्न वर्गों का उदाहरण न हो।

आपके मामले में, ImageIO.read(file)BufferedImage का एक उदाहरण देता है, जो मूल श्रेणी है। यह केवल तभी काम करेगा, अगर ImageIO.read(file)AdvancedBufferedImage या उसके उप-वर्गों का उदाहरण देता है।

जब आप कुछ कक्षा का विस्तार करते हैं, व्युत्पन्न वर्ग को बेस क्लास से कुछ गुण प्राप्त होते हैं, हालांकि, बेस क्लास कुछ भी हासिल नहीं करता है। इसके परिणामस्वरूप, व्युत्पन्न वर्ग के उदाहरण में बेस क्लास के सभी गुण होते हैं, बेस क्लास का संदर्भ व्युत्पन्न वर्ग का उदाहरण धारण कर सकता है, यानी आप एक समर्पित कक्षा को BASE कक्षा में डाल सकते हैं। अब, व्युत्पन्न कक्षा कुछ नई गुण जोड़ सकती है और बेस क्लास इन गुणों के बारे में कभी भी अवगत नहीं है। तो बीएएसई कक्षा से डेरिवेड का एक कलाकार स्पष्ट रूप से गलत है।

3

Downcasting in Java

downcasting इस तरह काम करने के लिए नहीं जा रहा है। उपर्युक्त पोस्ट में जवाब देखें। एक विकल्प के रूप में, एक स्थिर फैक्ट्री विधि बनाने के बारे में क्या है जो BufferedImage लेता है और ImageIO.read() द्वारा लौटाई गई वस्तु के साथ निर्मित आपकी कक्षा का एक उदाहरण देता है?

उदाहरण के लिए:

private AdvancedBufferedImage(BufferedImage bi) { 
    // build your AdvancedBufferedImage from bi 
    ... 
} 

public static AdvancedBufferedImage buildABI(BufferedImage bi) { 
    return new AdvancedBufferedImage(bi) 
+0

मैं देख रहा हूँ कि तुम क्या कहने की कोशिश कर रहे हैं, लेकिन इस मामले में वहाँ ठेकेदार में पैरामीटर जिसके लिए वहाँ ही टिककर खेल नहीं कर रहे हैं, इसलिए यह भी –

+0

को लागू करना था, तो मुझे लगता है कि संरचना आपके मामले में विरासत से बेहतर विचार है। क्या आपकी कक्षा में इसे विस्तारित करने के बजाय BufferedImage का ऑब्जेक्ट है? – Carl

0

BufferedImageएकAdvancedBufferedImage और इतने डाली विफल रहता नहीं है।

आप BufferedImage की कार्यक्षमता बढ़ा सकते हैं, लेकिन read विधि अभी भी केवल BufferedImage लौटाती है। कास्टिंग वांछित प्रकार के रूप में संदर्भ बनने, या व्यवहार करने के लिए मजबूर नहीं करता है।

आप शायद अपने AdvancedBufferedImage कक्षा में BufferedImage लपेटना चाहते हैं, तो आप अपने उन्नत कक्षा में चारों ओर गुजर सकते हैं और कुशलतापूर्वक उपयोग कर सकते हैं।

2

सामान्य रूप से, आप माता-पिता कक्षाओं को कक्षा कक्षाओं में नहीं डाल सकते हैं। एक कुत्ते को एक पशु डालने के लिए मजबूर करना पसंद है। एक कुत्ता एक जानवर है, लेकिन दूसरा तरीका हमेशा सत्य नहीं है, इसलिए जावा कंपाइलर आपको ऐसा करने की अनुमति नहीं देगा।

object inheritance देखें।

2

खिन्न अनुमति दी है, लेकिन यह चाहिए बच्चे का एक वास्तविक उदाहरण:

class A { 
    String name = "a"; 
    A(){}; 
} 

class B extends A { 
} 

public class Main { 
    public static void main(String[] args) { 
    A a = new B(); // must a b instance 
    B b = new B(); 
    b = (B)a; 
    System.out.println(b.name); 

    } 
}