आइए एक दूसरे के लिए उपेक्षा करें कि प्रश्न में विधि क्या है __constructऔर इसे कॉल करें frobnicate। अब मान लीजिए कि आपके पास एक वस्तु apiक्रियान्वयन है IHttpApi, और एक वस्तु configक्रियान्वयन IHttpConfig। स्पष्ट रूप से, यह कोड इंटरफ़ेस को फिट करता है:
$api->frobnicate($config)
लेकिन Upcast हम लगता है जाने apiके लिए IApiकरने के लिए इसे पारित, उदाहरण के लिए function frobnicateTwice(IApi $api)। अब उस फ़ंक्शन में, frobnicateकॉल किया जाता है, और चूंकि यह केवल डील करता है IApi, इसलिए यह एक कॉल कर सकता है जैसे कि $api->frobnicate(new SpecificConfig(...))जहां SpecificConfigलागू होता है IConfigलेकिन नहीं IHttpConfig। किसी भी बिंदु पर किसी ने भी प्रकार के साथ कुछ भी नहीं किया है, फिर IHttpApi::frobnicateभी एक SpecificConfigऐसा स्थान मिला जहां यह अपेक्षित था IHttpConfig।
यह अच्छा नहीं है। हम उपद्रव को रोकना नहीं चाहते हैं, हम सबटाइपिंग चाहते हैं, और हम स्पष्ट रूप से एक इंटरफ़ेस को लागू करने वाली कई कक्षाएं चाहते हैं। तो एकमात्र समझदार विकल्प एक उपप्रकार विधि को रोकना है जो मापदंडों के लिए अधिक विशिष्ट प्रकार की आवश्यकता होती है । (एक समान समस्या तब होती है जब आप अधिक सामान्य प्रकार वापस करना चाहते हैं ।)
औपचारिक रूप से, आप बहुरूपता, विचरण के आसपास के एक क्लासिक जाल में चले गए हैं । एक प्रकार की सभी घटनाओं को Tउपप्रकार द्वारा प्रतिस्थापित नहीं किया जा सकता है U। इसके विपरीत, एक प्रकार की सभी घटनाओं को सुपरपाइपT द्वारा प्रतिस्थापित नहीं किया जा सकता है । सावधानीपूर्वक विचार (या बेहतर अभी तक, प्रकार के सिद्धांत का सख्त अनुप्रयोग) आवश्यक है। S
वापस आ रहा है __construct: AFAIK के बाद से आप वास्तव में एक इंटरफ़ेस लागू नहीं कर सकते, केवल एक ठोस कार्यान्वयनकर्ता, यह एक व्यर्थ प्रतिबंध की तरह लग सकता है (यह कभी भी इंटरफ़ेस के माध्यम से कॉल नहीं किया जाएगा)। लेकिन उस मामले __constructमें, इंटरफ़ेस में शामिल क्यों करना शुरू करने के लिए? बावजूद, __constructयहां विशेष-मामले में इसका उपयोग बहुत कम होगा ।