2010-04-10 29 views
5

मैं एक सिस्टम लिख रहा हूं कि रनटाइम पर कुछ टेम्पलेट उत्पन्न करता है, और उसके बाद उन टेम्पलेट्स के आधार पर कुछ ऑब्जेक्ट उत्पन्न करता है। मैं विचार यह है कि टेम्पलेट्स कक्षा वर्ग के एक्सटेंशन हो सकता था, लेकिन है कि कुछ शानदार त्रुटियां हुईं:क्या क्लास क्लास का विस्तार करना कानूनी है?

VerifyError: Error #1107: The ABC data is corrupt, attempt to read out of bounds. 

क्या मैं सोच रहा हूँ कि अगर उपवर्गीकरण क्लास, यहां तक ​​कि संभव है, अगर वहाँ शायद कुछ मामले में जहां है ऐसा करना उचित होगा, न केवल ओओपी का एक बड़ा दुरुपयोग। मेरा मानना ​​है कि यह संभव होना चाहिए, क्योंकि एक्शनस्क्रिप्ट आपको क्लास प्रकार के चर बनाने की अनुमति देता है। इस उपयोग को LiveDocs entry for Class में वर्णित किया गया है, फिर भी मैंने कक्षा को उपclassing का कोई उल्लेख नहीं देखा है।

यहाँ एक स्यूडोकोड उदाहरण है:

class Foo extends Class 

var A:Foo = new Foo(); // A is a class 
trace(A is Class); // true, right? 
var b = new A(); // b is an instance of class A 

मुझे पता नहीं क्या b के प्रकार के हो जाएगा। क्या यह होगा?

trace(b is A); // true? 

लेकिन फिर, आप चर b, A टाइप करने के लिए var b:A = new A(); में के रूप में, यहां तक ​​कि A हालांकि क्रम जब तक अस्तित्व में नहीं है टाइप कर सकते हैं? मैंने पढ़ा है कि यह संभव नहीं है क्योंकि A स्थिर रूप से हल करने योग्य नहीं है, लेकिन मैं इस संभावना का पता लगाने के लिए अपने स्वयं के परीक्षण कर रहा हूं।

आखिरकार, उद्देश्य रनटाइम पर नए वर्गों को उत्पन्न करना है, और फिर उन वर्गों के उदाहरण बनाना है।

सारांश में: क्या आप कक्षा कक्षा को उप-वर्ग कर सकते हैं? यदि हां, तो आप त्रुटियों के बिना इसे कैसे कर सकते हैं, और कक्षा उप-वर्ग के उदाहरणों के उदाहरण किस प्रकार हैं?

+0

मुख्य प्रश्न यह है: कक्षा कक्षा है? –

+0

ठीक है, मैं वास्तव में पूछ रहा हूं कि क्या आप कक्षा वर्ग को उप-वर्ग कर सकते हैं, या यदि यह कक्षा मॉडल का दुरुपयोग है। मुझे पहले से ही पता है कि कक्षा एक वर्ग है; यहां क्लास क्लास लाइवोक है: http://help.adobe.com/en_US/AS3LCR/Flash_10.0/Class.html – ivanreese

+0

एक उदाहरण बी // सच्चे –

उत्तर

1

यहाँ मेरे अपने में गहराई से अनुसंधान के निष्कर्ष हैं।मेरी जांच से, अब मुझे आश्वस्त है कि क्लास क्लास में अन्य शीर्ष स्तर के वर्गों के सभी गुण शामिल नहीं हैं, भले ही वे ऑब्जेक्ट क्लास से विस्तारित हैं।

आगे निराशा तथ्य यह है कि विभिन्न शीर्ष स्तरीय कक्षाओं उपवर्गीकरण कई अलग अलग त्रुटि संदेश में परिणाम होगा, यह कुछ हद तक मुश्किल बताने के लिए क्या मुद्दों खेल में कर रहे हैं बना रही है। , एक सरल उदाहरण के साथ शुरू करने के लिए यदि आप ActionScript के आदिम डेटाटाइप्स (पूर्णांक, uint, संख्या, स्ट्रिंग, बूलियन, आदि) के कई उपवर्ग करते हैं तो आपको निम्नलिखित संकलक त्रुटि मिलती है:

1016: Base class is final. 

यह समझ में आता है क्योंकि इन कक्षाओं में से किसी के लिए डॉक्स को देखकर पता चलता है कि वे वास्तव में अंतिम हैं:

Package  Top Level 
Class   public final class Boolean 
Inheritance Boolean -> Object 

अंतिम कीवर्ड, ज़ाहिर है, इसका मतलब है कि किसी अन्य वर्ग वर्ग के रूप में अंतिम चिह्नित विस्तार नहीं हो सकता। अब एक और अधिक शामिल उदाहरण के लिए, फ़ंक्शन क्लास का विस्तार देखें। दस्तावेज़ों के मुताबिक फंक्शन क्लास अंतिम नहीं है। यह अंतिम नहीं है के बाद से, यह मतलब है हम अपने ही विशेष समारोह वस्तुओं को बनाने के समारोह वर्ग का विस्तार कर सकते हैं? .. और फिर क्रम पर

class MyFunction extends Function { /*...*/ } 

:

VerifyError: Error #1103: Class ::MyFunction cannot extend final base class. 

ऊपर आदिम डेटाप्रकार त्रुटि के साथ इसकी तुलना यहाँ एक परिभाषा है। यह त्रुटि संकलन समय पर हुई, क्योंकि विरासत में प्राचीन वर्ग को वास्तव में अंतिम रूप में चिह्नित किया गया था। समारोह वर्ग है नहीं अंतिम चिह्नित लेकिन वर्ग अभी भी व्यवहार करती है जैसे कि वह था, केवल रनटाइम पर।

अब, हम मुख्य प्रश्न के मुद्दे के लिए आते हैं: कक्षा वर्ग का विस्तार। फंक्शन क्लास के साथ, कक्षा वर्ग अंतिम नहीं है। इसके अलावा, कक्षा वर्ग गतिशील है, जिसका अर्थ है कि नए गुणों को रनटाइम पर क्लास ऑब्जेक्ट में जोड़ा जा सकता है।

एक दिलचस्प साइड-नोट के रूप में: फ़ंक्शन क्लास भी गतिशील है, और मुझे विश्वास है कि ईसीएमएस्क्रिप्ट बोली में मौजूद पुराने प्रोटोटाइप विरासत तंत्र के निरंतर समर्थन के लिए इस हिस्से का यह हिस्सा है। इस बोली में, कार्य एक तरह की कक्षाओं (अच्छी तरह से, प्रोटोटाइप) के रूप में उपयोग किया जाता है, और गुणों से युक्त कार्यों की सुविधा भी जोड़ी कार्यावधि में मूलरूप विरासत की शक्ति का हिस्सा है।

अब, यह मेरी समझ है कि एक वर्ग ऑब्जेक्ट के गुणों को स्थिर उस वर्ग के किसी भी मामले के लिए उपलब्ध गुण के रूप में ही हो रहा है। इस प्रकार, इसे तार्किक अर्थ बनाना चाहिए कि कोई रनटाइम पर क्लास ऑब्जेक्ट में हेरफेर करना चाहता है, जिससे वह उस वर्ग के व्यवहार को बदल सकता है और इसके उदाहरण हैं। कक्षा वर्ग गतिशील है इस धारणा को मजबूत करता है।

चूंकि कक्षा वर्ग अंतिम नहीं है, इसलिए मैं क्लास क्लास का अपना विशेषज्ञता बनाने और मेटा-भाषा डोमेन में कहीं भी काम करने के लिए क्लास क्लास का विस्तार कर सकता हूं, यह देखने के लिए उत्सुक था। मैं एक और दिन के लिए इस बारे में चर्चा करूंगा कि कोई ऐसा क्यों करना चाहेगा, और यह किस शक्ति को hypothetically अनुमति देगा। अब अंतिम उदाहरण के लिए, कक्षा कक्षा का विस्तार करें। यहां एक परिभाषा है:

// the definition causes no errors on its own, even though the compiler "sees" it 
class MyClass extends Class { /*...*/ } 

/* elsewhere */ 

MyClass; // the only mention of MyClass beyond the definition 

..और फिर क्रम पर:

verify global$init() 
        stack: 
        scope: 
        locals: global 

/* snip about 120 lines */ 

    46:getlex 34 
        stack: global Class$? 
        scope: global Object$ Class$ 
        locals: global 
    48:newclass MyClass$cinit() 
VerifyError: Error #1107: The ABC data is corrupt, attempt to read out of bounds. 

    at global$init() 

पवित्र स्टैकट्रेस! VerifyError विकृत एसडब्ल्यूएफ डेटा के लिए आरक्षित है। मुझे जो मिल सकता है उसके आधार पर, यह भी है कि फ्लैश प्लेयर में "बग" कैसे प्रकट होता है। किसी भी मामले में, यह एक सामान्य एक्शनस्क्रिप्ट त्रुटि से थोड़ा सा है।

इस बिंदु पर, यह समझना मुश्किल हो जाता है कि वास्तव में क्या हो रहा है, लेकिन यह वही है जो मैं अब तक कम करने में सक्षम हूं।

VerifyError: Error #1107: The ABC data is corrupt, attempt to read out of bounds. 

मैं (गलती से, टिप्पणी नीचे देखें) का मानना ​​है कि "एबीसी" सार बेस कक्षा, जो एक शब्द है कि instantiated नहीं किया जा सकता है, केवल बढ़ाया वर्गों के लिए आवेदन किया है के लिए खड़ा है। हालांकि, उपरोक्त भयानक त्रुटि तत्कालता के बिंदु पर नहीं आती है, लेकिन माइक्लास क्लास सबक्लास की पहली पहुंच पर। वास्तव में, उदाहरण का कोड, मैंने कभी एक MyClass ऑब्जेक्ट को तुरंत चालू नहीं किया है, मैं केवल MyClass क्लास को ही संदर्भित करता हूं।

मैंने कुछ और परीक्षण किए और पाया कि क्लास ऑब्जेक्ट्स में कम से कम, ऑब्जेक्ट सबक्लास से आने वाले प्रकार के निर्माता नहीं होते हैं। बस अपने कोड में कहीं भी new Class(); टाइप करना इस तथ्य को अच्छी तरह से प्रदर्शित करेगा, लेकिन आप .constructor संपत्ति, और अन्य चालों के निरीक्षण के द्वारा इसकी जांच कर सकते हैं। इसके परिणामस्वरूप, कक्षा वर्ग के उदाहरण सर्वश्रेष्ठ द्वितीय श्रेणी की वस्तुओं पर हैं, क्योंकि उन्हें रनटाइम पर नहीं बनाया जा सकता है।

पहले मुझे संदेह था कि यह मेरे गंदा VerifyError का सही कारण था। हालांकि, अब मुझे विश्वास है कि कक्षा में कई अन्य तत्व हैं, जो हमारे स्वयं के एक्शनस्क्रिप्ट कोड के लिए अदृश्य हैं, जो क्लास क्लास, फंक्शन क्लास या अन्य उत्सुक स्थानों में मौजूद हो सकते हैं या नहीं भी हो सकते हैं। निश्चित रूप से, जब फ़्लैश प्लेयर बेस क्लास के विस्तार के लिए आवश्यक लोगों में से किसी एक तक पहुंचने का प्रयास करता है, और यह अस्तित्व में नहीं है (क्योंकि कक्षा संभवतः एबीसी है, इस प्रकार सामान्य वर्ग में मौजूद कुछ तत्व गायब हैं), कोई भी उम्मीद कर सकता है VerifyError सीमाओं से बाहर देखने के लिए।

संक्षेप में, कक्षा कक्षा को विस्तारित करना इस समय असंभव प्रतीत होता है। ऐसा प्रतीत होता है कि कक्षा वर्ग में उन सभी गुणों को शामिल नहीं किया गया है जिनमें से अधिकांश शीर्ष स्तर के वर्ग ऑब्जेक्ट से प्राप्त होते हैं, हालांकि परीक्षण करना मुश्किल है।

मैं कक्षा को विस्तारित करने से अधिक विशिष्ट त्रुटि संदेश परिणाम देखना पसंद करूंगा, लेकिन फिलहाल ऐसी कोई चीज़ नहीं है। मुझे कुछ मेटाप्रोग्रामिंग क्षमता एक्शनस्क्रिप्ट पर वापस देखना अच्छा लगेगा। अभी के लिए यह जानना पर्याप्त है कि कम से कम, इस तरह से यह नहीं किया जा सकता है।

+0

एबीसी एक्शनस्क्रिप्ट बाइटकोड के लिए खड़ा है। आपके द्वारा पोस्ट किया गया वह पता एबीसी है जो अपवाद फेंकने पर निष्पादित होता है, अंतिम पंक्ति "newclass" opcode है। यदि आप न्यूक्लास (http://www.adobe.com/devnet/actionscript/articles/avm2overview.pdf) के लिए एवीएम दस्तावेज़ों की जांच करते हैं, तो आप देखेंगे कि बेस क्लास (इस मामले में, कक्षा और ऑब्जेक्ट) चालू होना चाहिए ढेर, और उनके स्थिर प्रारंभिक चलाए जाएंगे। शायद यह अपवाद की जड़ है - कक्षा में कोई स्थैतिक प्रारंभकर्ता नहीं है, और इसकी तलाश करने से बाहर की सीमाएं पढ़ी जाती हैं। – tclem

+0

tclem, लिंक के लिए धन्यवाद। मुझे नहीं पता था कि उन्होंने ऐसा दस्तावेज प्रदान किया है। मैं इसे पढ़ूंगा और जो कुछ सीखूं उसके साथ मेरी पोस्ट संशोधित करूंगा। – ivanreese

5

पहले पैराग्राफ में रहने वाले से यह Every Class object is an instance of the Class class. बताता है, इसलिए कक्षा को विस्तारित करने में त्रुटि होगी क्योंकि किसी भी वर्ग वस्तु पहले से ही कक्षा है।

आपने कहा a system that generates some templates, and then generates some objects based on those templates. ऐसा लगता है कि आप वास्तव में क्या करने की कोशिश कर रहे हैं एक इंटरफ़ेस बना रहा है।

जब आपका टेम्पलेट कोई कार्यान्वयन प्रदान नहीं करता है तो एक इंटरफ़ेस का उपयोग किया जाना चाहिए। यही है, आप खेतों और विधियों का एक गुच्छा घोषित करते हैं लेकिन विधियों का कोई कार्यान्वयन नहीं करते हैं। इस प्रकार आप इस तरह के एक वर्ग घोषणा करेंगे:

public interface Foo { 
    function bar:void; 
} 

अब एक वर्ग है कि इस अंतरफलक आप बस निम्नलिखित कर लागू करता है बनाने के लिए।

public class MyClass implements Foo { 
    function bar:void { 
     ..... implementation goes here ..... 
    } 
} 

कक्षा के लिए कई इंटरफेस लागू करना संभव है, जबकि यह केवल एक वर्ग का विस्तार कर सकता है।

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

उम्मीद है कि इससे मदद मिलती है। हालांकि यह अच्छी तरह से प्रलेखित नहीं है कहीं भी है कि मैंने अभी तक देखा है,

विस्तार श्रेणी वर्ग आंतरिक रूप से असंभव प्रतीत हो रहा है:

+0

मैट, आपके उत्तर के लिए धन्यवाद। मैं इस सवाल को थोड़ा और स्पष्ट करने जा रहा हूं, क्योंकि आपने इस मुद्दे को कवर किया है क्योंकि मैंने इसे अच्छी तरह प्रस्तुत किया है, फिर भी मुझे एहसास हुआ है कि मैंने अपने मन में उपयोग को पूरी तरह से निर्दिष्ट नहीं किया है। इंटरफेस इस मामले में काम नहीं करेंगे क्योंकि एक्शनस्क्रिप्ट में इंटरफ़ेस एक ऑब्जेक्ट प्रति से नहीं है (हालांकि यह दस्तावेज़ प्रकार के अनुसार डेटा प्रकार है), यह एक वर्ग का सार्वजनिक इंटरफ़ेस मानकीकृत करने के लिए उपयोग किया जाने वाला एक निर्माण है। जो मैं खोज रहा हूं वह एक वर्ग का ऑब्जेक्ट-प्रस्तुति है जिसे गतिशील रूप से छेड़छाड़ की जा सकती है और रनटाइम पर तुरंत चालू किया जा सकता है। – ivanreese

+0

इसके अलावा, पुन: आपका पहला अनुच्छेद: यह एक त्रुटि क्यों होगी? मुझे यह नहीं दिख रहा है, हालांकि ऐसा लगता है कि मैं इसका अनुभव कर रहा हूं (देखें: एबीसी त्रुटि)। यदि क्लास क्लास का प्रत्येक ऑब्जेक्ट क्लास क्लास का एक उदाहरण है, तो मैं क्लास क्लास का उप-वर्ग क्यों नहीं बना सकता, और उसके बाद उप-वर्ग के उदाहरण बना सकता हूं, क्योंकि उनके पास अभी भी अपने पूर्वजों में कक्षा कक्षा होगी? – ivanreese

+0

आखिरकार, जैसे ही मेरे पास 15 प्रतिनिधि हैं, मैं आपके उत्तर को वोट दूंगा। चूंकि यह मेरा पहला सवाल है, और आज मेरा पहला दिन सक्रिय रूप से साइट पर पोस्ट कर रहा है (हालांकि मैं लंबे समय से प्रशंसक और पाठक रहा हूं), बोर्ड पर आने से पहले मुझे थोड़ा सा समय लगेगा और पूरी तरह से भाग लेने में सक्षम है। फिर से धन्यवाद। – ivanreese

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