PHP में गैर-अमूर्त वर्ग में सार पद्धति कैसे घोषित करें?




abstract-function (6)

class absclass {
    abstract public function fuc();
}

रिपोर्ट:

PHP घातक त्रुटि: क्लास एब्सक्लास में 1 सार विधि होती है और इसलिए उसे सार घोषित किया जाना चाहिए या शेष विधियों को लागू करना चाहिए (absclass ::uc)

मैं जानना चाहता हूं कि शेष विधियों को लागू करने का क्या मतलब है, कैसे?


मैं एक गैर-अमूर्त वर्ग (सामान्य वर्ग?) के भीतर एक अमूर्त पद्धति का उपयोग करना चाहता था और मैंने पाया कि मैं get_parent_class () के साथ 'if' कथन में विधि की सामग्री को लपेट सकता हूं:

if (get_parent_class($this) !== false) {

या, कार्रवाई में (cmd लाइन पर एक फ़ाइल में परीक्षण किया गया: php -f "abstract_method_normal_class_test.php"):

<?php
    class dad {
        function dad() {
            if (get_parent_class($this) !== false) {
                // implements some logic
                echo "I'm " , get_class($this) , "\n";
            } else {
                echo "I'm " , get_class($this) , "\n";
            }
        }
    }

    class child extends dad {
        function child() {
            parent::dad();
        }
    }

    $foo = new dad();
    $bar = new child();
?>

Output:
I'm dad
I'm child

PHP get_parent_class () प्रलेखन


आप इस त्रुटि संदेश से थोड़े से भटक रहे हैं। इस मामले में, चूंकि यह इस वर्ग के भीतर है कि fuc परिभाषित किया जा रहा है, यह वास्तव में इस वर्ग में इसे लागू करने के लिए समझ में नहीं आएगा। जो त्रुटि आपको बताने की कोशिश कर रहा है वह यह है कि एक गैर-अमूर्त वर्ग में अमूर्त विधियां नहीं हो सकती हैं। जैसे ही आप एक वर्ग की परिभाषा में एक अमूर्त विधि डालते हैं, आपको कक्षा को भी सार के रूप में चिह्नित करना होगा।


एक अमूर्त वर्ग सीधे तात्कालिक नहीं हो सकता है, लेकिन इसमें अमूर्त और गैर-अमूर्त दोनों तरीके हो सकते हैं।

यदि आप एक सार वर्ग का विस्तार करते हैं, तो आपको अपने सभी सार कार्यों को लागू करना होगा, या उपवर्ग को अमूर्त बनाना होगा।

आप एक नियमित विधि को ओवरराइड नहीं कर सकते हैं और इसे अमूर्त बना सकते हैं, लेकिन आपको (अंततः) सभी अमूर्त विधियों को ओवरराइड करना चाहिए और उन्हें गैर-अमूर्त बनाना चाहिए।

<?php

abstract class Dog {

    private $name = null;
    private $gender = null;

    public function __construct($name, $gender) {
        $this->name = $name;
        $this->gender = $gender;
    }

    public function getName() {return $this->name;}
    public function setName($name) {$this->name = $name;}
    public function getGender() {return $this->gender;}
    public function setGender($gender) {$this->gender = $gender;}

    abstract public function bark();

}

// non-abstract class inheritting from an abstract class - this one has to implement all inherited abstract methods.
class Daschund extends Dog {
    public function bark() {
        print "bowowwaoar" . PHP_EOL;
    }
}

// this class causes a compilation error, because it fails to implement bark().
class BadDog extends Dog {
    // boom!  where's bark() ?
}

// this one succeeds in compiling, 
// it's passing the buck of implementing it's inheritted abstract methods on to sub classes.
abstract class PassTheBuckDog extends Dog {
    // no boom. only non-abstract subclasses have to bark(). 
}

$dog = new Daschund('Fred', 'male');
$dog->setGender('female');

print "name: " . $dog->getName() . PHP_EOL;
print "gender: ". $dog->getGender() . PHP_EOL;

$dog->bark();

?>

इस कार्यक्रम के साथ बम:

PHP घातक त्रुटि: क्लास बडोग में 1 सार विधि शामिल है और इसलिए उसे सार घोषित किया जाना चाहिए या शेष विधियों को लागू करना चाहिए (डॉग :: छाल)

यदि आप BadDog क्लास को कमेंट करते हैं, तो आउटपुट है:

name: Fred
gender: female
bowowwaoar

यदि आप सीधे एक कुत्ते या एक PassTheBuckDog को इस तरह से करने की कोशिश करते हैं:

$wrong = new Dog('somma','it');
$bad = new PassTheBuckDog('phamous','monster');

..इसके साथ बम:

PHP घातक त्रुटि: अमूर्त वर्ग कुत्ते को तत्काल नहीं कर सकता

या (यदि आप $ गलत लाइन टिप्पणी करते हैं)

PHP घातक त्रुटि: अमूर्त वर्ग PassTheBuckDog को तत्काल नहीं कर सकता

हालाँकि, आप किसी अमूर्त वर्ग के स्थिर कार्य को कॉल कर सकते हैं:

abstract class Dog {
    ..
    public static function getBarker($classname, $name, $gender) {
        return new $classname($name, $gender);
    }
    ..
}

..

$other_dog = Dog::getBarker('Daschund', 'Wilma', 'female');
$other_dog->bark();

यह ठीक काम करता है।


एब्स्ट्रैक्ट कीवर्ड का इस्तेमाल क्लास या तरीकों को पैटर्न के रूप में लेबल करने के लिए किया जाता है। यह इंटरफेस के समान है लेकिन इसमें चर और विधियों का कार्यान्वयन हो सकता है।

अमूर्त वर्गों के विषय में बहुत सी गलतफहमियाँ हैं। यहाँ एक सार डॉग क्लास का उदाहरण दिया गया है। यदि कोई डेवलपर अन्य डेवलपर्स के लिए या खुद को विस्तारित करने के लिए कुछ मूल डॉग क्लास बनाना चाहता है तो वह क्लास को सार घोषित करता है। आप डॉग क्लास को सीधे (कोई भी नहीं) कर सकते हैं, लेकिन आप डॉग को अपनी कक्षा के द्वारा बढ़ा सकते हैं। स्मार्टडॉग कुत्ते आदि का विस्तार करता है।

डॉग क्लास द्वारा अमूर्त घोषित किए जाने वाले सभी तरीकों को डॉग का विस्तार करने वाले प्रत्येक वर्ग में मैन्युअल रूप से लागू किया जाना चाहिए।

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


PHP मैनुअल में क्लास एब्स्ट्रेक्शन पर अध्याय देखें:

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

इसका मतलब आपको या तो करना है

abstract class absclass { // mark the entire class as abstract
    abstract public function fuc();
}

या

class absclass {
    public function fuc() { // implement the method body
        // which means it won't be abstract anymore
    };
}

मुझे लगता है कि शेष विधियां वास्तव में उन अमूर्त तरीकों को संदर्भित करती हैं जिन्हें आप परिभाषित करने की कोशिश कर रहे हैं (इस मामले में, fuc() ), क्योंकि गैर-अमूर्त तरीके जो मौजूद हो सकते हैं वैसे भी ठीक हैं। यह शायद एक त्रुटि संदेश है जो एक बेहतर शब्द का उपयोग कर सकता है: जहां यह शेष कहता है उसे सार कहना चाहिए।

फिक्स बहुत सीधा है (त्रुटि संदेश का वह भाग ठीक है): आपको इसे बदलने की आवश्यकता है:

abstract public function fuc();

... एक उचित कार्यान्वयन में:

public function fuc(){
    // Code comes here
}

... या, वैकल्पिक रूप से और अपनी आवश्यकताओं के आधार पर, पूरे वर्ग को सारगर्भित बनाएँ:

abstract class absclass {
    abstract public function fuc();
}






abstract-function