PHP中看似多态的东西真的是多态的吗?

试图弄清楚PHP是否支持方法重载,继承和多态性等功能,我发现:

  • 它不支持方法重载
  • 它确实支持继承

但我不确定多态性。我发现这个谷歌搜索互联网:

我应该注意,在PHP中,多态性并不是它应该有的样子。我的意思是它确实有效,但是由于我们的数据类型较弱,因此它不正确。

那么它真的是多态性吗?

编辑只是不能在旁边放置一个明确的“是”或“否”。我不愿意说:“PHP不支持多态性”,而实际上它确实如此。反之亦然。PHP supports polymorphism


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

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

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>';
}

你可以随心所欲地标记它,但这对我来说就像是多态的。


答案 2

尽管PHP不支持您在其他语言中遇到的方法重载,例如Java。但是你可以在PHP中有方法重载,但定义方法是不同的。如果你想为给定的方法使用不同的功能,在PHP中使用不同的参数集,你可以做这样的事情:

class myClass {
    public function overloadedMethod() {
        // func_num_args() is a build-in function that returns an Integer.
        // the number of parameters passed to the method.
        if ( func_num_args() > 1 ) {
            $param1 = func_get_arg(0);
            $param2 = func_get_arg(1);
            $this->_overloadedMethodImplementation2($param1,$param2)
        } else {
            $param1 = func_get_arg(0);
            $this->_overloadedMethodImplementation1($param1)
        }
    }

    protected function _overloadedMethodImplementation1($param1) {
        // code 1
    }

    protected function _overloadedMethodImplementation2($param1,$param2) {
        // code 2
    }
}

可能有更清晰的实现,但这只是一个示例。

PHP支持继承和接口。所以你可以使用它们进行多态性。你可以有一个这样的界面:

// file: MyBackupInterface.php
interface MyBackupInterface {
    // saves the data on a reliable storage
    public function saveData();
    public function setData();
}

// file: myBackupAbstract.php
require_once 'MyBackupInterface.php';
class MyBackupAbstract implements MyBackupInterface {
     protected $_data;
     public function setData($data) {
         $this->_data= $data;
     }
     // there is no abstract modifier in PHP. so le'ts avoid this class to be used in other ways
     public function __construct() {
          throw new Exception('this class is abstract. you can not instantiate it');
     }
}

// file: BackupToDisk.php
require_once 'MyBackupAbstract.php';
class BackupToDisk extends MyBackupAbstract {
     protected $_savePath;

     // implement other methods ...

     public function saveData() {
           // file_put_contents() is a built-in function to save a string into a file.
           file_put_contents($this->_savePath, $this->_data);
     }
}

// file: BackupToWebService.php
require_once 'MyBackupAbstract.php';
class BackupToWebService extends MyBackupAbstract {
     protected $_webService;
     // implement other methods ...

     public function saveData() {
           // suppose sendData() is implemented in the class
           $this->sendData($this->_data);
     }
}

现在在您的应用程序中,您可以像这样使用它:

// file: saveMyData.php
// some code to populate $myData
$backupSolutions = array( new BackupToDisk('/tmp/backup') , new BackupToWebService('webserviceURL') );
foreach ( $backupSolutions as $bs ) {
    $bs->setData($myData);
    $bs->saveData();
}

你是对的,PHP不是强类型语言,我们从来没有提到过你的任何$backupSolutions将是“MyBackupAbstract”或“MyBackupInterface”,但这不会阻止我们具有多态性的性质,这是使用相同方法的不同功能。


推荐