2012-01-17 12 views
11

मेरे पास कक्षाओं का एक समूह है जो एक अमूर्त वर्ग का विस्तार करता है। अमूर्त वर्ग में ऐसे विधियां हैं जो बाल कक्षाओं में परिभाषित जानकारी प्राप्त करने के लिए देर से स्थिर बाइंडिंग का उपयोग करती हैं। उदाहरण के लिए, अमूर्त वर्ग एक विधि लाइन युक्त हो सकता है:PHP - एक वर्ग को संपत्ति घोषित करने के लिए मजबूर करें

$var = static::$childVar . ' some text'; 

इस तरह, यह विधि अमूर्त वर्ग में परिभाषित एक चर के मूल्य के आधार पर विभिन्न तार उत्पन्न करने के लिए के लिए कार्यावधि में संभव है बाल वर्गों में परिभाषित किया गया।

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

इंटरफेस का उपयोग करना, विधियों को परिभाषित करने के लिए कक्षा की आवश्यकता होती है (और स्थिरांक, दुर्भाग्य से सार्वजनिक/संरक्षित/निजी का उपयोग करके उनकी दृश्यता में संशोधन नहीं हो सकता है)। तो यदि कोई वर्ग इंटरफ़ेस लागू करता है, लेकिन इंटरफ़ेस में निर्दिष्ट सभी विधियों को परिभाषित नहीं करता है, तो एक त्रुटि उत्पन्न होती है। हालांकि, किसी संपत्ति को परिभाषित करने के लिए कक्षा की आवश्यकता के लिए इंटरफ़ेस का उपयोग करने का कोई तरीका नहीं है।

मैंने कुछ सामग्री देखी है जो इंटरफ़ेस में गेटर विधियों का उपयोग करने का सुझाव देती है (उदाहरण के लिए getChildVar()) को स्पष्ट रूप से परिवर्तनीय घोषणा की आवश्यकता है, लेकिन यह मेरे लिए उपयुक्त नहीं है क्योंकि मैं नहीं चाहता कि वेरिएबल कक्षा के बाहर पहुंच योग्य हों (उनके पास protected दृश्यता है)।

इसी प्रकार, स्थिरांक काम नहीं करेंगे, क्योंकि वे protected दृश्यता संशोधक का समर्थन नहीं करते हैं।

मैं जानता हूँ कि मैं हमेशा अमूर्त वर्ग की विधि (या यहां तक ​​कि निर्माता में) में इस के लिए जाँच करने के लिए एक isset() बयान इस्तेमाल कर सकते हैं, लेकिन यह सुनिश्चित करने के तरीकों परिभाषित कर रहे हैं के लिए इंटरफेस के उपयोग की तुलना में असजीला लगता है। मैं सोच रहा हूं कि मेरे अमूर्त वर्ग में आवश्यकताओं को हार्डकोड किए बिना ऐसा करने का कुछ मानक तरीका है या नहीं।

संयोग से, अगर कोई जानता है कि आप इंटरफेस के अंदर चर क्यों घोषित नहीं कर सकते हैं, तो मुझे यह जानने में दिलचस्पी होगी कि तर्क क्या है। यह मेरे लिए एक बड़ी निगरानी की तरह लगता है।

किसी भी मदद की बहुत सराहना की जाएगी।

उत्तर

10

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

अभी निरीक्षण की बात यह है कि आपके पास एक अनिर्धारित स्थिर संपत्ति तक पहुंचने का प्रयास करने के लिए जादू विधि नहीं हो सकती है। यह आपके लिए यहां आदर्श समाधान होगा।

यदि स्थिर संपत्ति रनटाइम पर घोषित की जाती है, तो setChildVar() विधि को लागू क्यों न करें, या एक पैरेंट-क्लास विधि डालें जो देर से स्थैतिक-बाध्य संपत्ति प्राप्त करती है और सेट होने पर त्रुटि उत्पन्न करती है? आप इसे पूरा करने के लिए "ड्राइवर" पैटर्न भी कार्यान्वित कर सकते हैं:

<?php 

class MyParentClass { 

    public function __get($key) 
    { 
     if (!isset(static::$$key)) 
     { 
      throw new Exception('Child class '.get_called_class().' failed to define static '.$key.' property'); 
     } 

     return static::$$key; 
    } 

    public function getText() 
    { 
     return $this->childVar . ' some text'; 
    } 

} 

class MyChildClass extends MyParentClass { 

    protected static $childVar = 'some value:'; 

} 

$a = new MyChildClass; 
echo $a->getText(); // some value: some text 
+0

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

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