第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

PHP中的“重載”是個(gè)啥?

標(biāo)簽:
PHP

很多面试官在面试的时候都会问一些面向对象的问题,面向对象的三大特性中,多态最主要的实现方式就是方法的重载和重写。但是在PHP中,只有重写,并没有完全的重载能力的实现。

重写,子类重写父类方法。

// 重写
class A
{
    public function test($a)
    {
        echo 'This is A:' . $a, PHP_EOL;
    }
}

class childA extends A
{
    public function test($a)
    {
        echo 'This is A child:' . $a, PHP_EOL;
    }
}

$ca = new childA();
$ca->test(1);

这个在PHP中是没有任何问题的,子类可以重写父类的方法。当实例化子类的时候,调用的就是子类实现的重写的方法。

重载,相同方法名但参数数量或者类型不同。

class A{
    function foo($a){
        echo $a;
    }
    // Fatal error: Cannot redeclare A::foo()
    function foo($a, $b){
        echo $a+$b;
    }
}

抱歉,这样写的结果将会是直接的报错。PHP并不支持这样的重载能力。而在PHP的官方手册上,重载的定义是使用__set()、__get()、__call()、__callStatic()等魔术方法来对无法访问的变量或方法进行重载。这与我们所学习的面向对象中的重载完全不同,在手册中的note里也有很多人对此提出了疑问。当然,我们今天并不会再去讲这些魔术方法的使用。

那么,在PHP中可以实现重载吗?当然可以,只不过会麻烦一些:

// 重载
class B
{
    public function foo(...$args)
    {
        if (count($args) == 2) {
            $this->fooAdd(...$args);
        } else if (count($args) == 1) {
            echo $args[0], PHP_EOL;
        } else {
            echo 'other';
        }
    }

    private function fooAdd($a, $b)
    {
        echo $a + $b, PHP_EOL;
    }
}

$b = new B();
$b->foo(1);
$b->foo(1, 2);

使用一个方法来调用其他方法,根据参数数量来进行判断,就可以实现参数数量不同的方法重载。

// 使用__call()进行重载
class C
{
    public function __call($name, $args)
    {
        if ($name == 'foo') {
            $funcIndex = count($args);
            if (method_exists($this, 'foo' . $funcIndex)) {
                return $this->{'foo' . $funcIndex}(...$args);
            }
        }
    }

    private function foo1($a)
    {
        echo $a, PHP_EOL;
    }

    private function foo2($a, $b)
    {
        echo $a + $b, PHP_EOL;
    }

    private function foo3($a, $b, $c)
    {
        echo $a + $b + $c, PHP_EOL;
    }

}

$c = new C();
$c->foo(1);
$c->foo(1, 2);
$c->foo(1, 2, 3);

使用__call()魔术方法或许会更简单,但也会让一些新手在接手项目的时候蒙圈。毕竟魔术方法对IDE是不友好的,这样的开发让__call()成为了一个模板方法,由它来定义操作的算法骨架。我们也可以根据参数类型来模拟重载能力。

// 参数类型不同的重载
class D {
    function __call($name, $args){
        if($name == 'foo'){
            if(is_string($args[0])){
                $this->fooString($args[0]);
            }else {
                $this->fooInt($args[0]);
            }
        }
    }
    private function fooInt(int $a){
        echo $a . ' is Int', PHP_EOL;
    }

    private function fooString(string $a){
        echo $a . ' is String', PHP_EOL;
    }
}

$d = new D();
$d->foo(1);
$d->foo('1');

不管怎么说,用上述方法实现的方法重载都非常麻烦,因为会让某一个方法或者魔术方法非常重,它需要成为一个控制器来根据参数对内部的方法进行调度。更多的情况下,我们应该还是使用不同的方法名然后抽象公共的部分提取成独立的私有内部方法来实现不同方法名的“重载”。毕竟不同的语言还是要掌握它们不同的个性,并且根据这些个性灵活地运用在我们的项目中。

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消