2010-01-09 16 views
5

प्रश्न मेरी आवश्यकताओं को बेहतर ढंग से प्रतिबिंबित करने के लिए संपादित किया गया।कॉलिंग अभिभावक कक्षा के तरीके


निम्न उदाहरण लें:

class Base 
{ 
    public $Text = null; 

    public function __construct() 
    { 
     $this->Text = new Base_Text(); 
    } 
} 

class Base_Text extends Base 
{ 
    public $Is = null; 

    public function __construct() 
    { 
     $this->Is = new Base_Text_Is(); 
    } 

    public function CammelCase($string) 
    { 
     return trim(str_replace(' ', '', ucwords($string))); 
    } 
} 

class Base_Text_Is extends Base_Text 
{ 
    public function CammelCase($string) 
    { 
     return ($string === $this->CammelCase($string)); // doesn't work 
    } 
} 

मैं कैसे स्थिर Base_Text वर्ग बुला बिना Base_Text_Is::CammelCase() विधि को ठीक कर सकते हैं (parent:: या Base_Text:: का उपयोग नहीं)?

function Base() 
{ 
    static $instance = null; 

    if (is_null($instance) === true) 
    { 
     $instance = new Base(); 
    } 

    return $instance; 
} 

और यह करने के लिए Base_Text_Is::CammelCase() पद्धति को बदलने:

return ($string === Base()->Text->CammelCase($string)); 

और क्रम में

एकमात्र समाधान मैं स्थितियों के इस प्रकार के लिए के साथ आया था इस तरह की एक सिंगलटन समारोह बनाने के लिए है बेस वर्ग के दो वस्तु उदाहरणों बनाने के बजाय, कर से बचने के लिए:

$base = new Base(); 
$base->Text->Is->CammelCase('MethodOverloading'); // true 

मैं सिर्फ कार्य करें:

Base()->Text->Is->CammelCase('MethodOverloading'); // true 

यह एक अच्छा अभ्यास है? क्या कोई अन्य समाधान है?

+0

मैं डॉन ' Darrell के जवाब में अपनी आखिरी टिप्पणी नहीं प्राप्त करें। आप 'Base_Text' की गैर स्थैतिक गुणों तक पहुंचने में सक्षम नहीं हैं? आप उन्हें कहां से कॉल करना चाहते हैं? मुझे लगता है कि आपको इसे और समझा जाना चाहिए। –

+0

@ फ़ेलिक्स: मैं उदाहरण को यथासंभव सरल रखने की कोशिश कर रहा हूं, ऐसे मामले हैं जब मैं मूल रूप से मूल विधि को कॉल नहीं कर सकता क्योंकि यह तत्काल गुणों पर निर्भर करता है। –

उत्तर

7

अपने प्रश्न के दिल यहाँ निहित है:

कैसे कर सकते हैं बेटा :: बी() कहते हैं पिताजी :: ए() पद्धति गैर स्थिर ( माता-पिता या पिताजी का उपयोग किए बिना)?

उत्तर बस है, यह नहीं हो सकता है। Son::A() के साथ आप Dad::A() को ओवरराइड करते हैं। A() की एकमात्र अवधारणा है कि अब सोनी ऑब्जेक्ट का यह A() है। आपको मूल विधि को स्थैतिक रूप से, या पूरी तरह से Dad ऑब्जेक्ट उदाहरण पर कॉल करना होगा।

नीचे पंक्ति है, यदि आप माता-पिता A() विधि को कॉल करना चाहते हैं, तो आप इसे पहले स्थान पर ओवरराइड करने के लिए परेशान क्यों हैं?

आपकी संरचना या तो कोई समझ नहीं लेती है। आप $dad->A() पर कॉल क्यों चाहते हैं, इसे $dad->son->A() पर पास करें, जो बदले में $dad->son->B() पर कॉल करेगा, जो तब आप पूछ रहे हैं, $dad->A() पर कॉल करें? यह एक अनंत लूप है।

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

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

संपादित

मैं तुम्हें बहुत ज़्यादा विरासत पर जा चुका है।

$base = new Base(); 
$base->Text->Is->CammelCase('MethodOverloading'); // true 

तो सभी कार्यक्षमता बच्चे कक्षाओं में है, तो आप Base वर्ग instantiating नहीं किया जाना चाहिए: वहाँ कोई कारण नहीं है यदि आप ऐसा करने दिया जाना चाहिए। यह कुछ इस तरह होना चाहिए:

$text = new Text(); 
$text->isCamelCase('someString'); 

आपका कोड बहुत सभी परिपत्र माता पिता/बच्चे हटाया instantiations और विशिष्ट बच्चे कक्षाओं के लिए नीचे धक्का दे दिया कार्यक्षमता के साथ, सरल किया जा सकता:

class Base 
{ 
    //don't put anything related to child classes here, 
    //unless it is going to provide specific functionality 
} 

class Text extends Base 
{ 
    public function CamelCase($string) 
    { 
     return trim(str_replace(' ', '', ucwords($string))); 
    } 

    public function isCamelCase($string) 
    { 
     return ($string === $this->CamelCase($string)); 
    } 
} 
+0

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

+0

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

+0

@ ज़ोंबैट: मैं अपने आखिरी संपादन के प्रकाश में पूछना चाहूंगा, अगर आपको अभी भी लगता है कि विरासत को फिर से डिजाइन करना एक अच्छा विचार है (यदि हां, कोई पॉइंटर्स?) और यदि 'बेस()' सिंगलटन फ़ंक्शन का उपयोग करना है) इस परिदृश्य में एक बुरा अभ्यास। –

1

मुझे नहीं लगता कि बच्चे से माता-पिता को इसे स्थिर रूप से कॉल करने या parent:: का उपयोग करने के लिए एक तरीका है। हालांकि मैं इस सवाल को गलत समझ सकता हूं। पुत्र() का एक उदाहरण बनाना दो वस्तुओं को नहीं बनाता है। पुत्र पिताजी को बढ़ाता है लेकिन यह अभी भी एक वस्तु है।

यदि आप पिता के अंदर सिंगलटन के साथ पिताजी() को फोन करने जा रहे हैं तो इसे बेटे से क्यों बढ़ाएं?

+0

मैंने अपने प्रश्न को एक और यथार्थवादी उदाहरण के साथ अपडेट किया है, कृपया इसे देखें। –

+0

मैं अभी भी 'पैरेंट ::' का उपयोग करने के लिए अपने विचलन को समझ नहीं पा रहा हूं। –

+0

यह एक विचलन नहीं है, मैं इसका उपयोग नहीं कर सकता क्योंकि अगर मैं करता हूं तो मैं 'बेस_Text' गैर स्थैतिक गुणों तक पहुंचने में सक्षम नहीं हूं। –

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