ट्रैक
/
PHP
PHP
/
सिलेबस
/
कोवेरिएंस और कॉन्ट्रावेरिएंस
को

कोवेरिएंस और कॉन्ट्रावेरिएंस में PHP

{one: "1 अभ्यास", other: "%{count} अभ्यास"}

कोवेरिएंस और कॉन्ट्रावेरिएंस के बारे में

कोवेरिएंस और कॉन्ट्रावेरिएंस

यूनियन टाइप का इस्तेमाल करते समय आपको कोवेरिएंस और कॉन्ट्रावेरिएंस की अवधारणाएँ समझना ज़रूरी है। इन्हें डॉक्यूमेंटेशन में समझाया गया है, लेकिन ये उदाहरण इन्हें समझने में मदद कर सकते हैं।

मान लीजिए हमारे पास एक Calculator क्लास है, जो ऊपर दिए उदाहरण जैसा ही एक फंक्शन इस्तेमाल करती है:

class Calculator
{
    public function add(int|float $x, int|float $y): int|float
    {
        return $x + $y;
    }
}

अगर आप इस क्लास से एक नई क्लास बनाते हैं, तो आपको पैरामीटर टाइप और रिटर्न टाइप बदलने की अनुमति है, लेकिन केवल नीचे दिए नियमों के अनुसार।

सबसे पहले, पैरामीटर टाइप "चौड़े" हो सकते हैं, यानी वे बेस क्लास की तुलना में अधिक टाइप स्वीकार कर सकते हैं। उदाहरण के लिए, यह मान्य है:

class StringCalc extends Foo
{
    public function add(float|int|string $x, float|int|string $y): int|float
    {
        if (!is_numeric($x) || !is_numeric($y)) {
            throw new \InvalidArgumentException('$x and $y must be numeric');
        }
        return $x + $y;
    }
}

हम मूल Calculator क्लास की जगह StringCalc क्लास रख सकते हैं और सब कुछ वैसे ही काम करेगा। जो कोड इन फंक्शन को कॉल करता है, वह अब भी वही float या int भेज पाएगा जो वह पहले भेज सकता था, और रिटर्न टाइप भी अब भी वही अपेक्षित int या float रहेगा।

इसी तरह, आप रिटर्न टाइप को छोटा कर सकते हैं, यानी यूनियन से टाइप हटाकर उसे और विशिष्ट बना सकते हैं। यह उदाहरण इसी नियम का फायदा उठाता है:

class IntCalc extends Calculator
{
    public function add(float|int $x, float|int $y) : int
    {
        return (int)($x + $y);
    }
}

चूँकि IntCalc क्लास अब भी int और float स्वीकार करती है, यह बिना किसी समस्या के मूल Calculator क्लास की जगह ले सकती है।

क्या मान्य है और क्या नहीं, इसके बारे में और पढ़ने के लिए आप Liskov Substitution Principal (LSP) देख सकते हैं।

जो मान्य नहीं होगा, उसका उदाहरण नीचे दिए InvalidCalc में देखिए:

class InvalidCalc extends Calculator
{
    public function add(int $x, int $y) : int|float|string
    {
        // Declaration must be compatible with Calculator->add(x: float|int, y: float|int)

        // Return type declaration must be compatible with Calculator->add(x: float|int, y: float|int) : float|int
    }
}

InvalidCalc क्लास कंपाइल नहीं होगी और उसमें दो समस्याएँ हैं। पैरामीटर के तौर पर क्या स्वीकार किया जा सकता है, इसे सीमित करने की वजह से InvalidCalc मूल Calculator क्लास की जगह नहीं ले सकती, क्योंकि अब यह float स्वीकार नहीं करती। इसके अलावा, अब यह string भी लौटा सकती है, जो मूल क्लास के मान्य रिटर्न टाइप में शामिल नहीं है।

GitHub के ज़रिए संपादित करें यह लिंक नई विंडो या टैब में खुलता है।