Difference between Abstract Class and Interface – PHP एक Pure Object Oriented Programming / Scripting Language नहीं है। इसमें तीन Concepts Operator Overloading, Function Overloading व Multiple Inheritance को Implement नहीं किया जा सकता। लेकिन जावा की तरह ही PHP में Interface को Implement किया जा सकता है।
Interface वास्तव में Indirectly Multiple Inheritance की सुविधा देते हैं। हालांकि Interface पूरी तरह से Multiple Inheritance के सभी Features को Support नहीं करते, लेकिन फिर भी कुछ हद तक हम Multiple Inheritance जैसी सुविधा Interfaces द्वारा प्राप्त कर सकते हैं।
Interface वास्तव में एक तरह की Pure Abstract Class होती है, जिसके सभी Data Members Constant होते हैं, जबकि सभी Methods Unimplemented होते हैं। यानी Interface के सभी Methods की Interface की Body में केवल Declaration होती है और हम किसी भी Method का Definition Interface में Specify नहीं कर सकते।
इसी तरह से हम किसी Interface में Member Variable Declare नहीं कर सकते। Interface में हम केवल Constants को ही Declare कर सकते हैं, जिन्हें Class के अन्दर self:: Expression द्वारा Access किया जा सकता है, जहां self Current Class को Refer करता है। जबकि Constants को बिना किसी तरह का Access Specify किए हुए Directly Specify करना होता है।
Interface को Exactly Class की तरह ही Create व Extend किया जाता है। अन्तर केवल इतना है कि Class के Methods को हम हमारी जरूरत के अनुसार किसी भी Access Scope Specifier के साथ Declare कर सकते हैं, लेकिन Interface के सभी Members को Public रखना जरूरी होता है। किसी Interface को Create करने के लिए हमें निम्न Syntax को Follow करना होता हैः
interface IinterfaceName { const constantNames = Value; public methodNames(); }
क्योंकि जैसाकि हमने पहले भी कहा Interface वास्तव में एक तरह की Abstract Class ही होते हैं, इसलिए जिस तरह से हम किसी Class को Extend करते हैं, उसी तरह से हम किसी Interface की सभी General Functionalities को भी किसी दूसरे Interface में Extend कर सकते हैं। जैसेः
interface IinterfaceName { const constantNames = Value; public methodNames(); } interface IinterfaceNameA extends IinterfaceName{ const constantNamesA = Value; public methodNamesA(); }
उपरोक्त Syntax की तरह जब हम IinterfaceName Interface को IinterfaceNameA Interface में Extend करते हैं, तो IinterfaceName Interface के सभी Unimplemented Methods व Constants IinterfaceNameA नाम के Interface में Available हो जाते हैं, ठीक उसी तरह से जिस तरह से Base Class के सभी Accessible Members Derived Class में Available हो जाते हैं।
हालांकि हम किसी एक Class को एक से ज्यादा Base Classes से Derive नहीं कर सकते, लेकिन हम एक Interface को एक से ज्यादा Interfaces से Derive कर सकते हैं। एक से ज्यादा Interfaces को किसी एक Derived Interface में Inherit करने के लिए हमें निम्न Syntax का प्रयोग करना होता हैः
interface IinterfaceNameA { const constantNamesA = Value; public methodNamesA(); } interface IinterfaceNameB { const constantNamesB = Value; public methodNamesB(); } interface IinterfaceName extends IinterfaceNameA, IinterfaceNameB{ const constantNames = Value; public methodNames(); }
जब हम किसी Interface को Create करते हैं, तो उसके सभी Members Undefined होते हैं। इसलिए जब तक हम इन Members को Define नहीं करते, तब तक इन Members का कोई औचित्य नहीं होता। इसलिए हम जिस Class में इन Members को Define करना चाहते हैं, उस Class में हमें हमारे Interface को Implement करना होता है।
किसी Class में किसी Interface को Implement करने के लिए हमें जावा की तरह ही implements Keyword का प्रयोग करना होता है। इस पूरी प्रक्रिया को हम निम्न उदाहरण द्वारा बेहतर तरीके से समझ सकते हैं:
<?php interface Person{ public function setData($name, $fname, $contactNo, $city, $state); public function getData(); } class Employee implements Person{ public function setData($name, $fname, $contactNo, $city, $state){ $this->name = $name; $this->fname = $fname; $this->contactNo = $contactNo; $this->city = $city; $this->state = $state; } public function display(){ Echo "Name: " . $this->name . "\n"; Echo "Father Name: " . $this->fname . "\n"; Echo "Contact Number: " . $this->contactNo . "\n"; Echo "City: " . $this->city . "\n"; Echo "State: " . $this->state . "\n"; } public function getData(){} } $rahul = new Employee; $rahul->setData('Sohan Lal', 'Mohan Lal', '9898989898', 'Falna', 'Rajasthan'); $rahul->display(); ?> //Output Name: Sohan Lal Father Name: Mohan Lal Contact Number: 9898989898 City: Falna State: Rajasthan
जैसाकि उपरोक्त Program व उसके Output में हम देख सकते हैं कि ये Program Exactly हमारे पहले बनाए गए Abstract Class की तरह ही काम कर रहा है और वैसा ही Output भी Generate कर रहा है, क्योंकि वास्तव में Interface एक तरह का Pure Abstract Class ही होता है।
Abstract Class की तरह ही यदि हम किसी Implemented Interface में Declare किए गए सभी Unimplemented methods को Implement नहीं करते हैं, तो भी हमें वैसी ही Error प्राप्त होती है, जैसी Abstract Class में Declare किए गए सभी Undefined Methods को Derived Class में Define न करने पर प्राप्त होती है। जैसेः
<?php interface Person{ public function setData($name, $fname, $contactNo, $city, $state); public function getData(); } class Employee implements Person{ public function setData($name, $fname, $contactNo, $city, $state){ $this->name = $name; $this->fname = $fname; $this->contactNo = $contactNo; $this->city = $city; $this->state = $state; } public function display(){ Echo "Name: " . $this->name . "\n"; Echo "Father Name: " . $this->fname . "\n"; Echo "Contact Number: " . $this->contactNo . "\n"; Echo "City: " . $this->city . "\n"; Echo "State: " . $this->state . "\n"; } } $rahul = new Employee; $rahul->setData('Sohan Lal', 'Mohan Lal', '9898989898', 'Falna', 'Rajasthan'); $rahul->display(); ?> //Output PHP Fatal error: Class Employee contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Person::getData) in C:\w amp\www\phpInHindi\001.php on line 23 PHP Stack trace: PHP 1. {main}() C:\wamp\www\phpInHindi\001.php:0 Fatal error: Class Employee contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Person::getData) in C:\wamp\w ww\phpInHindi\001.php on line 23 Call Stack: 0.0011 336096 1. {main}() C:\wamp\www\phpInHindi\001.php:
इस Program में हमने Interface के getData() Method को Implement नहीं किया है। परिणामस्वरूप हमें निम्नानुसार Fatal Error प्राप्त होता है, जो कि ठीक Abstract Class की तरह का ही Reaction है। यदि हम किसी Abstract Class के सभी abstract Methods को Derived Class में Implement न करें, तब भी PHP हमें इसी तरह का Fatal Error देता है।
PHP में हम दो ऐसे Interfaces को एक ही Class में Implement नहीं कर सकते, जिनमें एक ही नाम के दो Methods हों अथवा दो Interface यदि समान Methods को Share कर रहे हों, तो हम उन दोनों Interfaces को एक ही Class में Implement नहीं कर सकते। जैसेः
<?php interface A { public function input(); public function display(); } interface B { public function input(); public function display(); } class C implements A, B{ function display(){ Echo "Hello! "; } function input(){} } $d = new C; $d->display(); ?>
यदि हम उपरोक्त Code के अनुसार दो Interfaces A व B को Class C में Implement करते हैं, जिनमें input() व display() नाम के Common Methods हैं, तो हमें निम्नानुसार Error Message प्राप्त होता है, क्योंकि PHP में हम ऐसा नहीं कर सकतेः
//Output PHP Fatal error: Can't inherit abstract function B::input() (previously declared abstract in A) in C:\wamp\www\phpInHindi\001.php on line 12 PHP Stack trace: PHP 1. {main}() C:\wamp\www\phpInHindi\001.php:0 Fatal error: Can't inherit abstract function B::input() (previously declared abstract in A) in C:\wamp\www\phpInHindi\001.php on line 12 Call Stack: 0.0006 331192 1. {main}() C:\wamp\www\phpInHindi\001.php:0
इसी तरह से किसी Interface में किसी Method को Declare करते समय उस Method में हम जितने Arguments Specify करते हैं, Method को Class में Implement करते समय भी हमें उतने ही Arguments Specify करने जरूरी होते हैं। यानी Interface व Class दोनों में Method का Signature Exactly Match होना जरूरी होता है, अन्यथा PHP Fatal Error Trigger करता है।
<?php interface ShapeArea { const PI = 3.1415; public function input($rad); public function display(); } class Circle implements ShapeArea { private $radius; public function input($rad){ $this->radius = $rad; } public function circleArea(){ return 2 * self::PI * $this->radius * $this->radius; } function display(){ Echo "Area of Circle : " . $this->circleArea(); } } $button = new Circle; $button->input(14); $button->display(); ?> //Output Area of Circle : 1231.468
इस Program में हमने ShapeArea नाम का एक Interface Create किया है, साथ ही इसमें PI नाम का एक Constant भी Define किया है। चूंकि Constant को Declare करते ही उसमें Value Initialize करना जरूरी होता है, इसलिए हमनें इस Constant में Value के रूप में 3.1415 मान Store कर दिया है। फिर हमने इस Interface में input(), व display() नाम के दो Method Declare किए हैं और अन्त में हमने इस Interface को Circle नाम की एक Class में Implement किया है।
फिर हमने input() नाम के Method को Define किया है, जो Circle Class के Object के लिए Value Accept करने का काम करता है। जबकि display() नाम के Method द्वारा Circle के Area को Display करने के लिए Define किया है।
Circle का Area Calculate करने के लिए हमने circleArea() नाम का एक Method Create किया हैं। ये Method ShapeArea Interface में Define किए गए Constant PI के मान को Current Class में Access करने के लिए self::PI Expression का प्रयोग करता है।
चूंकि Interface को जब किसी Class में Implement किया जाता है, तब उस Interface में Define किए गए Constant को Access करने के लिए हमें Interface के नाम के बाद Scope Resolution Operator का प्रयोग करके फिर Constant का नाम Specify करना होता है। लेकिन हमने इस Program में Interface के नाम के स्थान पर self Keyword का प्रयोग किया है। ये Keyword Current Class को Refer करता है।
चूंकि जब Interface को Implement किया जाता है, तब उस Interface के सभी Accessible Members उस Class में Available हो जाते हैं, जिसमें Interface को Implement किया गया है, इसलिए ShapeArea Interface का Constant PI भी Circle नाम की Class में ठीक उसी तरह से Available हो गया है, जैसे कि इस PI नाम के Constant को Circle Class में ही Define किया गया हो।
इसीलिए समान circleArea() Method में Class को Refer करने के लिए हम self Keyword का प्रयोग कर सकते हैं। फलस्वरूप हमने Interface के नाम के स्थान पर self Keyword का प्रयोग किया है।
self Keyword का प्रयोग करने का मुख्य कारण ये है कि हालांकि हम Interface के नाम के साथ Scope Resolution Operator का प्रयोग करके भी PI के मान को Access कर सकते थे, लेकिन यदि हम ऐसा करते, तो Interface का नाम Class के Code में Hard Code हो जाता।
परिणामस्वरूप यदि कभी भविष्टय में हम Interface के नाम को किसी कारण से Change कर देते, तो फिर हमने उस Interface को जिस-जिस Class में जहां-जहां Use किया है, हमें हर उस Class को फिर से Modify करना पडता।
जबकि यही काम self:: Keyword को Use करके पूरा करने की वजह से यदि हम Interface के नाम को Change भी कर दें, तो कम से कम हमें हर Class के अन्दर के Codes को Change करने की जरूरत नहीं होगी, बल्कि हमें केवल उन सभी Classes के साथ Specify किए गए Interface के नाम को ही Modify करना होगा, जिसमें हमने Interface को Implement किया है।
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook PHP in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी।
PHP in Hindi | Page: 647 | Format: PDF