2011-12-17 11 views
25

चूंकि केवल कुत्ते "fetch" खेल सकते हैं, क्या यह उदाहरण एक अच्छा या बुरा विचार है? मुझे संदेह है कि उदाहरण के उपयोग के कारण यह वास्तव में एक बुरा विचार है, लेकिन मुझे पूरा यकीन नहीं है कि क्यों।PHP उदाहरणों के साथ सामान्य पॉलिमॉर्फिज्म

class Animal { 
    var $name; 
    function __construct($name) { 
     $this->name = $name; 
    } 
} 

class Dog extends Animal { 
    function speak() { 
     return "Woof, woof!"; 
    } 

    function playFetch() { 
     return 'getting the stick'; 
    } 
} 

class Cat extends Animal { 
    function speak() { 
     return "Meow..."; 
    } 
} 

$animals = array(new Dog('Skip'), new Cat('Snowball')); 

foreach($animals as $animal) { 
    print $animal->name . " says: " . $animal->speak() . '<br>'; 
    if ($animal instanceof Dog) echo $animal->playFetch(); 
} 

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

class Data_Object { 
    protected $_id; 

    function setId($id) { 
     $this->_id = $id; 
    } 

    function getId() { 
     return $this->_id; 
    } 
} 

class Dog extends Data_Object { 
    protected $_name; 
    function setName($name) { 
     $this->_name = 
    } 

    function getName() { 
     return $this->_name; 
    } 
} 

class Chair extends Data_Object { 
    protected $_numberOfWheels; 
    function setNumberOfWheels($number) { 
     $this->_numberOfWheels = $number; 
    } 

    function getNumberOfWheels() { 
     return $this->_numberOfWheels; 
    } 
} 

अनिवार्य रूप से मैं क्या सोचता मैं पूछ रहा हूँ है: "सभी उपवर्गों एक ही इंटरफ़ेस होना चाहिए या वे अलग-अलग हो सकती है?"

+2

सुंदर यकीन है कि यह यहाँ कहा गया है इससे पहले कि बहुरूपता को संभालने के लिए है, लेकिन संक्षिप्त उत्तर यह ठीक है उपवर्गों एक अलग इंटरफेस के लिए के लिए है। – NullUserException

+0

मुझे पूरा यकीन है कि पहला उदाहरण सशर्त तर्क के उदाहरण के उपयोग के कारण सही नहीं है। पॉलिमॉर्फिज्म का पूरा बिंदु यह नहीं है? – Dan

+0

आप सभी जानवरों को एक प्रकार (कुत्ता) को छोड़कर कुछ (बोलने) क्यों करना चाहते हैं? दोषपूर्ण तर्क की तरह लगता है कि लूप में, वर्ग परिभाषा नहीं है। – NullUserException

उत्तर

44

इस संदर्भ में इंटरफेस के बारे में बात करना उपयोगी है।

interface Talkative { 
    public function speak(); 
} 

class Dog extends Animal implements Talkative { 
    public function speak() { 
     return "Woof, woof!"; 
    } 
} 

किसी भी पशु या मानव (या विदेशी) को लागू करता है कि बातूनी इंटरफ़ेस एक संदर्भ में इस्तेमाल किया जा सकता है, जहां बातूनी प्राणियों की जरूरत है:

protected function makeItSpeak(Talkative $being) { 
    echo $being->speak(); 
} 

यह एक ठीक से इस्तेमाल किया बहुरूपी विधि है। आपको परवाह नहीं है आप तब तक काम कर रहे हैं जब तक यह speak() हो सकता है।

यदि Dog एस भी fetch खेल सकते हैं, यह उनके लिए बहुत अच्छा है। यदि आप इसे सामान्य बनाना चाहते हैं, तो इसके बारे में एक इंटरफ़ेस के संदर्भ में भी सोचें। शायद एक दिन आपको एक अत्यधिक प्रशिक्षित बिल्ली मिलेगी जो भी fetch खेल सकते हैं।

class Cog extends Cat implements Playfulness { 
    public function playFetch() { ... } 
} 

महत्वपूर्ण बात यहाँ किया जा रहा है जब आप कॉल कुछ पर playFetch(), क्योंकि यह आपको लगता है कि जानवर के साथ लाने खेलना चाहते हैं कि। आप playFetch पर कॉल नहीं करते हैं, ठीक है ... आप कर सकते हैं, लेकिन क्योंकि आप इस पल में fetch खेलना चाहते हैं। यदि आप fetch खेलना नहीं चाहते हैं, तो आप इसे कॉल नहीं करते हैं। यदि आपको किसी निश्चित स्थिति में लाने की आवश्यकता है, तो आपको कुछ ऐसी चीज चाहिए जो fetch खेल सके। आप इसे इंटरफेस घोषणाओं के माध्यम से सुनिश्चित करते हैं।

आप कक्षा विरासत का उपयोग करके एक ही चीज़ प्राप्त कर सकते हैं, यह केवल कम लचीला है। ,

abstract class Animal { } 

abstract class Pet extends Animal { } 

class Dog extends Pet { 
    public function playFetch() { ... } 
} 

class GermanShepherd extends Dog { 
    public function beAwesome() { ... } 
} 

फिर कुछ विशिष्ट संदर्भ में, आप किसी भी वस्तु है कि कुछ (इंटरफेस) कर सकते हैं की आवश्यकता नहीं कर सकते हैं , लेकिन आप विशेष रूप से एक GermanShepherd लिए देख रहे हैं: कुछ स्थितियों में, जहां कठोर पदानुक्रम हालांकि यह अस्तित्व में पूरी तरह से उपयोगी है क्योंकि केवल यह भयानक हो सकता है:

protected function awesomeness(GermanShepherd $dog) { 
    $dog->beAwesome(); 
} 

हो सकता है कि सड़क के नीचे आप GermanShepherd कि भी कमाल के हैं की एक नई नस्ल बना देंगे, लेकिन extendGermanShepherd वर्ग। वे अभी भी इंटरफेस की तरह awesomeness फ़ंक्शन के साथ काम करेंगे।

आपको निश्चित रूप से क्या नहीं करना चाहिए यादृच्छिक चीजों के गुच्छा के माध्यम से लूप करना, जांचें कि वे क्या हैं और उन्हें अपनी खुद की चीज़ बनाते हैं।यह किसी भी संदर्भ में बहुत समझदार नहीं है।

+5

इंटरफेस के बारे में एक PHP डेवलपर टॉक देखने के लिए यह ताज़ा है। मैं उन्हें php में बहुत उपयोग करता हूं, लेकिन अधिकांश प्रमुख ढांचे में कोई प्यार नहीं होता है, और इस प्रकार आम PHP डेवलपर द्वारा विचारधारा का बहुत कम गोद लेना होता है। –

+0

@deceze महान उत्तर। लेकिन मुझे आश्चर्य है कि क्या लक्षण यहां उल्लेखनीय हैं। http://www.php.net/manual/en/language.oop5.traits.php –

+0

@ मुहम्मद वास्तव में नहीं, आईएमओ। लक्षण संकेतक प्रकार नहीं हैं और इसलिए चर्चा के लिए कुछ हद तक अप्रासंगिक हैं। – deceze

22

PHP में बहुरूपता के लिए एक और उदाहरण

<?php 
interface Shape { 
    public function getArea(); 
} 

class Square implements Shape { 
    private $width; 
    private $height; 

    public function __construct($width, $height) { 
     $this->width = $width; 
     $this->height = $height; 
    } 

    public function getArea(){ 
     return $this->width * $this->height; 
    } 
} 

class Circle implements Shape { 
    private $radius; 

    public function __construct($radius) { 
     $this->radius = $radius; 
    } 

    public function getArea(){ 

     return 3.14 * $this->radius * $this->radius; 
    } 
} 

function calculateArea(Shape $shape) { 
    return $shape->getArea(); 
} 

$square = new Square(5, 5); 
$circle = new Circle(7); 

echo calculateArea($square), "<br/>"; 
echo calculateArea($circle); 
?> 
2

लगभग के रूप में आप कृष्णदास, ब्रैड ही। यह लेख मुझे समझ में बहुत मदद की कैसे पीएचपी

में

http://code.tutsplus.com/tutorials/understanding-and-applying-polymorphism-in-php--net-14362

interface shape_drawer{ 
    public function draw(Shape $obj); 
} 

class circle implements shape_drawer{ 
    public function draw(Shape $obj){ 
     echo "Drawing Circle, Area: {$obj->area} <br>"; 
    } 
} 

class square implements shape_drawer{ 
    public function draw(Shape $obj){ 
     echo "Drawing Square, Area: {$obj->area} <br>"; 
    } 
} 

class triangle implements shape_drawer{ 
    public function draw(Shape $obj){ 
     echo "Drawing Triangle, Area: {$obj->area} <br>"; 
    }  
} 

class shape_factory{ 
    public static function getShape(){ 

     $shape = $_REQUEST['shape']; 

     if(class_exists($shape)) { 
      return new $shape(); 
     } 
     throw new Exception('Unsupported format'); 
    } 
} 

class Shape{ 

    public function __construct($area){ 
     $this->area = $area; 
    } 
    public function draw(shape_drawer $obj) { 
     return $obj->draw($this); 
    } 
} 


$shape = new Shape(50); 
try { 
    $drawer = shape_factory::getShape(); 
} 
catch (Exception $e) { 
    $drawer = new circle(); 
} 

echo $shape->draw($drawer); 
संबंधित मुद्दे