2009-12-16 17 views

उत्तर

67

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

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

<?php 
    class Car 
    { 
     public static function run() 
     { 
      return static::getName(); 
     } 

     private static function getName() 
     { 
      return 'Car'; 
     } 
    } 

    class Toyota extends Car 
    { 
     public static function getName() 
     { 
      return 'Toyota'; 
     } 
    } 

    echo Car::run(); // Output: Car 
    echo Toyota::run(); // Output: Toyota 
?> 

late static bindings काम:

एक उदाहरण देखते हैं। स्थैतिक विधि कॉल के मामले में, यह वर्ग स्पष्ट रूप से नामित है (आमतौर पर :: ऑपरेटर के बाईं ओर वाला एक); गैर स्थैतिक विधि कॉल के मामले में, यह वस्तु का वर्ग है।

ए 'अग्रेषण कॉल "एक स्थिर एक है कि self::, parent::, static::, या द्वारा शुरू की गई है, अगर वर्ग पदानुक्रम, forward_static_call() में जा रहा है।

फ़ंक्शन get_called_class() का उपयोग कक्षा के नाम से एक स्ट्रिंग को पुनर्प्राप्त करने के लिए किया जा सकता है और static:: इसके दायरे को पेश करता है।

निम्नलिखित कोड 'AlphaBeta' पैदा करता है:

158

आपको निश्चित रूप से PHP मैनुअल में Late Static Bindings पढ़ने की आवश्यकता है। हालांकि, मैं आपको एक त्वरित सारांश देने की कोशिश करूंगा।

असल में, यह इस तथ्य को उबालता है कि self कीवर्ड विरासत के नियमों का पालन नहीं करता है। self हमेशा उस वर्ग का समाधान करता है जिसमें इसका उपयोग किया जाता है। इसका अर्थ यह है कि यदि आप अभिभावक वर्ग में कोई विधि बनाते हैं और उसे बच्चे वर्ग से कॉल करते हैं, तो self उस बच्चे का संदर्भ नहीं देगा जैसा आप उम्मीद कर सकते हैं।

देर स्थिर बाध्यकारी static कीवर्ड के लिए एक नया उपयोग प्रस्तुत करता है, जो इस विशेष कमी को संबोधित करता है। जब आप static का उपयोग करते हैं, तो यह उस वर्ग का प्रतिनिधित्व करता है जहां आप इसे पहले इस्तेमाल करते हैं, यानी। यह रनटाइम कक्षा में 'बांधता है'।

ये इसके पीछे दो बुनियादी अवधारणाएं हैं। जिस तरह से self, parent और static संचालित होते हैं जब static खेल में है सूक्ष्म हो सकता है, इसलिए अधिक विस्तार से जाने के बजाय, मैं दृढ़ता से अनुशंसा करता हूं कि आप मैन्युअल पृष्ठ उदाहरणों का अध्ययन करें। एक बार जब आप प्रत्येक कीवर्ड की मूल बातें समझ लेते हैं, तो उदाहरण यह देखने के लिए आवश्यक हैं कि आप किस प्रकार के परिणाम प्राप्त करने जा रहे हैं।

+24

+1 आपका वर्णन सरल और एक PHP में पाया की तुलना में स्पष्ट है मैनुअल। – Mouli

+2

यह स्वीकार्य उत्तर होना चाहिए। यह आसान और सहायक है –

+0

मुझे यह लेख वास्तव में उपयोगी और वर्णनात्मक पाया गया है, इसे देखें [लिंक] (https://www.techflirt.com/tutorials/oop-in-php/late-static-binding.html) –

4

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

abstract class Builder { 
    public static function build() { 
     return new static; 
    } 
} 

class Member extends Builder { 
    public function who_am_i() { 
     echo 'Member'; 
    } 
} 

Member::build()->who_am_i(); 
20

वहाँ बहुत स्पष्ट व्यवहार नहीं है।

class alpha { 

    function classname(){ 
     return __CLASS__; 
    } 

    function selfname(){ 
     return self::classname(); 
    } 

    function staticname(){ 
     return static::classname(); 
    } 
} 

class beta extends alpha { 

    function classname(){ 
     return __CLASS__; 
    } 
} 

$beta = new beta(); 
echo $beta->selfname(); // Output: alpha 
echo $beta->staticname(); // Output: beta 

हालांकि, अगर हम बीटा वर्ग से classname समारोह की घोषणा निकालने के लिए, हम 'alphaalpha' परिणाम के रूप में मिलता है।

+1

यह दिलचस्प है । मुझे खुद को – instead

+1

देखना बहुत अच्छा था। एक ही चीज़ PHP मैनुअल में दिखाया गया है, लेकिन यह बहुत स्पष्ट है। संदर्भ के लिए: http://php.net/manual/en/language.oop5.late-static-bindings.php (पूर्व देखें 4) – musicin3d

9

मैं पुस्तक से उद्धृत कर रहा हूं: "PHP मास्टर अत्याधुनिक कोड लिखते हैं"।

देर स्थिर बाध्यकारी PHP 5.3 के साथ पेश की गई एक विशेषता थी। यह हमें अभिभावक वर्ग से स्थिर विधियों का वारिस करने और को बाल वर्ग कहने के लिए संदर्भित करने की अनुमति देता है।

इसका मतलब है आप स्थिर तरीकों के साथ एक अमूर्त वर्ग हो सकता है, और स्थिर :: विधि() अंकन स्वयं :: विधि() का उपयोग कर के बजाय द्वारा संदर्भ बच्चे वर्ग के ठोस कार्यान्वयन।

रूप में अच्छी तरह सरकारी php प्रलेखन पर एक नज़र लेने के लिए स्वतंत्र महसूस: http://php.net/manual/en/language.oop5.late-static-bindings.php

उदाहरण:

<?php 
class Animal { 
    public static function StaticCall() { 
     // Parent object invokes its own getAnimalName() 
     // Child object invokes its own getAnimalName() instead of parent's getAnimalName() 
     return static::getAnimalName(); 
    } 

    public static function SelfCall() { 
     return self::getWeight(); 
    } 

    private static function getAnimalName(){ 
     return 'Animal <br />'; 
    } 

    private static function getWeight(){ 
     return '10 kg <br />'; 
    } 
} 

class Bird extends Animal { 
    public static function getAnimalName(){ 
     return 'Bird <br />'; 
    } 

    private static function getWeight(){ 
     return '2 kg <br />'; 
    } 
} 

echo Animal::StaticCall(); // Animal  
echo Animal::SelfCall(); // 10 kg   
echo Bird::StaticCall(); // Bird invokes method from own object 
echo Bird::SelfCall();  // 10 kg invokes method from parent 

कोड ऊपर आप दो वर्गों Animal देख सकते हैं जो माता पिता के वर्ग है में और Bird जो कि बाल वर्ग है। Animal और Bird दोनों में getAnimalName() और getWeight() विधि है। सुपरक्लास Animal में दो विधियां हैं: StaticCall() और SelfCall()

विधि StaticCall() static कीवर्ड का उपयोग कर getAnimalName() को आमंत्रित करता है।
विधि SelfCall() कीवर्ड का उपयोग कर getWeight() को आमंत्रित करता है।

हमारे पास अब सवाल है: किस संदर्भ में getAnimalName() निष्पादित किया गया है?

उत्तर: static::getAnimalName() संदर्भ की पहचान करता है और उस संदर्भ में विधि को आमंत्रित करता है।

यदि आप Bird::StaticCall() का आह्वान करते हैं तो कोड StaticCall() निष्पादित करेगा जो Animal में है। फिर static::getAnimalName()Bird विधि getAnimalName() से आवेदक और निष्पादित करेगा।

यह self:: से अलग है, क्योंकि self:: हमेशा वस्तु self भीतर विधि invokes में परिभाषित किया गया है। तो अगर self::getWeight() विधि SelfCall() में वस्तु Animal में परिभाषित किया गया है और Bird::SelfCall() तो कहा जा सकता है self::getWeight()Animal वस्तु के संदर्भ में getWeight() का आह्वान ।

4

इसे "मैं इसका उपयोग क्यों करूं?" से देख रहा हूं परिप्रेक्ष्य, यह मूल रूप से उस संदर्भ को बदलने का एक तरीका है जिससे स्थैतिक विधि का अर्थ/चलाया जा रहा है।

self के साथ, संदर्भ वह है जहां आपने मूल रूप से विधि को परिभाषित किया था। static के साथ, यह वह है जिसे आप इसे कॉल कर रहे हैं।

7

अंतर दिखाने के लिए सबसे सरल उदाहरण।
ध्यान दें, स्वयं :: $ ग

class A 
{ 
    static $c = 7; 

    public static function getVal() 
    { 
     return self::$c; 
    } 
} 

class B extends A 
{ 
    static $c = 8; 
} 

B::getVal(); // 7 

लेट स्टेटिक बंधन, ध्यान दें स्थिर :: $ ग

class A 
{ 
    static $c = 7; 

    public static function getVal() 
    { 
     return static::$c; 
    } 
} 

class B extends A 
{ 
    static $c = 8; 
} 

B::getVal(); // 8