2012-04-29 14 views
33

को परिभाषित करने के लिए एक बच्चे वर्ग को मजबूर करें मैंने देखा कि आपके पास PHP में सार स्थिरांक नहीं हो सकते हैं।PHP में सार स्थिरांक - निरंतर

क्या कोई तरीका है कि मैं एक बच्चे को कक्षा को स्थिर करने के लिए मजबूर कर सकता हूं (जिसे मुझे सार तत्वों में से एक में उपयोग करने की आवश्यकता है)?

+0

एक बार यह प्रत्येक स्कोप, फ़ंक्शन विधि या क्या नहीं है, इसे एक बार सेट करने के लिए एक पूर्ण दायरा है। इसका कोई मतलब नहीं है, कृपया कुछ और प्रदान करने के लिए कुछ कोड प्रदान करें। –

+2

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

उत्तर

25

constantconstant है; PHP में कोई abstract या private स्थिरांक के रूप में तक मुझे पता है वहाँ है, लेकिन आप के चारों ओर एक काम हो सकता है:

नमूना सार कक्षा

abstract class Hello { 
    const CONSTANT_1 = 'abstract'; // Make Abstract 
    const CONSTANT_2 = 'abstract'; // Make Abstract 
    const CONSTANT_3 = 'Hello World'; // Normal Constant 
    function __construct() { 
     Enforcer::__add(__CLASS__, get_called_class()); 
    } 
} 

यह ठीक चल पाएंगे

class Foo extends Hello { 
    const CONSTANT_1 = 'HELLO_A'; 
    const CONSTANT_2 = 'HELLO_B'; 
} 
new Foo(); 

बार त्रुटि वापस आएगा

class Bar extends Hello { 
    const CONSTANT_1 = 'BAR_A'; 
} 
new Bar(); 

Songo वापसी होगी त्रुटि

class Songo extends Hello { 

} 
new Songo(); 

लागू करने वाले के कक्षा

class Enforcer { 
    public static function __add($class, $c) { 
     $reflection = new ReflectionClass($class); 
     $constantsForced = $reflection->getConstants(); 
     foreach ($constantsForced as $constant => $value) { 
      if (constant("$c::$constant") == "abstract") { 
       throw new Exception("Undefined $constant in " . (string) $c); 
      } 
     } 
    } 
} 
+2

यह स्थिर नहीं है, यह एक कार्य है। – Zombaya

+0

@ ज़ोंबाया अवलोकन के लिए धन्यवाद .. मैंने बहुत जल्दी जमा करने पर क्लिक किया .. आशा है कि आप अब नीचे वोट पर विचार कर सकते हैं .. धन्यवाद ... – Baba

+6

:) मैं पुनर्विचार करता हूं, इसके बजाय एक उपेक्षा है। – Zombaya

6

नहीं, अभी आप इस तरह के सार तरीके के रूप में अन्य तरीकों से कोशिश कर सकते:

abstract class Fruit 
{ 
    abstract function getName(); 
    abstract function getColor(); 

    public function printInfo() 
    { 
     echo "The {$this->getName()} is {$this->getColor()}"; 
    } 
} 

class Apple extends Fruit 
{ 
    function getName() { return 'apple'; } 
    function getColor() { return 'red'; } 

    //other apple methods 
} 

class Banana extends Fruit 
{ 
    function getName() { return 'banana'; } 
    function getColor() { return 'yellow'; } 

    //other banana methods 
} 

या स्थिर सदस्य:

abstract class Fruit 
{ 
    protected static $name; 
    protected static $color; 

    public function printInfo() 
    { 
     echo "The {static::$name} is {static::$color}"; 
    } 
} 

class Apple extends Fruit 
{ 
    protected static $name = 'apple'; 
    protected static $color = 'red'; 

    //other apple methods 
} 

class Banana extends Fruit 
{ 
    protected static $name = 'banana'; 
    protected static $color = 'yellow'; 

    //other banana methods 
} 

Source

+3

यदि आप वेब पर कहीं और से कोड कॉपी करते हैं, तो सुनिश्चित करें कि आप स्रोत का हवाला देते हुए भी हैं। उपर्युक्त कोड http://www.sitepoint.com/forums/showthread.php?629565-Abstract-constants – Gordon

+1

से लिया गया था यह स्वीकार्य उत्तर के बाद बेहतर है। यदि एक अमूर्त वर्ग बाल वर्ग पर निर्भर करता है, तो इस निर्भरता की घोषणा करने के लिए एक अमूर्त विधि को परिभाषित करें और कार्यान्वयन वर्ग से मूल्य प्राप्त करने के लिए विधि का उपयोग करें। – Kwebble

15

दुर्भाग्य से नहीं ... एक निरंतर वास्तव में क्या यह टिन, निरंतर पर कहते है। एक बार परिभाषित किए जाने पर इसे फिर से परिभाषित नहीं किया जा सकता है, इसलिए इस तरह, PHP की अमूर्त विरासत या इंटरफेस के माध्यम से इसकी परिभाषा की आवश्यकता होती है।

हालांकि ... आप यह देखने के लिए जांच सकते हैं कि निरंतर कक्षा के निर्माता में निरंतर परिभाषित किया गया है या नहीं। यदि ऐसा नहीं होता है, तो एक अपवाद फेंक दें।

abstract class A 
{ 
    public function __construct() 
    { 
     if (!defined('static::BLAH')) 
     { 
      throw new Exception('Constant BLAH is not defined on subclass ' . get_class($this)); 
     } 
    } 
} 

class B extends A 
{ 
    const BLAH = 'here'; 
} 

$b = new B(); 

यह आपके सबसे अच्छे तरीके से ऐसा करने का सबसे अच्छा तरीका है।

+4

एक बच्चे के वर्ग में निरंतर मूल्य को ओवरराइड किया जा सकता है। स्थिरांक उस तरह के पुनर्वितरण के प्रति प्रतिरोधी नहीं हैं। – Brilliand

11

यह एक 'हैक' का थोड़ा सा हो सकता है, लेकिन बहुत कम प्रयास के साथ नौकरी करता है, लेकिन अगर बच्चे वर्ग में निरंतर घोषित नहीं किया जाता है तो एक अलग त्रुटि संदेश के साथ।

एक स्वयं निर्देशात्मक लगातार घोषणा वाक्य रचना सही है और समस्या के बिना पार्स करता है, केवल एक त्रुटि फेंक अगर उस घोषणा वास्तव में, रनटाइम पर निष्पादित किया जाता है तो अमूर्त वर्ग में एक आत्म निर्देशात्मक घोषणा चाहिए एक बच्चे कक्षा में अधिरोहित जा अन्यथा घातक त्रुटि होगी: Cannot declare self-referencing constant

इस उदाहरण में, सार, मूल वर्ग Foo अपने सभी बच्चों को परिवर्तनीय NAME घोषित करने के लिए मजबूर करता है। यह कोड Donald आउटपुट को ठीक करता है।हालांकि, अगर बच्चे वर्ग Foolingनहीं चर घोषित करता है, तो घातक त्रुटि ट्रिगर की जाएगी।

<?php 

abstract class Foo { 

    // Self-referential 'abstract' declaration 
    const NAME = self::NAME; 

} 

class Fooling extends Foo { 

    // Overrides definition from parent class 
    // Without this declaration, an error will be triggered 
    const NAME = 'Donald'; 

} 

$fooling = new Fooling(); 

echo $fooling::NAME; 
+1

धन्यवाद @WebSmithery –

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