2014/11/07

Abstract Interface Traits 差異

PHP 對於 class 的使用方式很多,在這邊做一下筆記整理。

Basic

<?php

class Main
{
    public function foo()
    {
        echo 'foo';
    }
}

class Sub extends Main
{
    public function bar()
    {
        echo 'bar';
    }
}

$sub = new Sub;
$sub->bar(); // bar
$sub->foo(); // foo

這是最基本的 class 應用,Sub extends 了 Main,因此可以在 Sub 拿到 protected 以及 public 的變數以及使用 function。

Interface

<?php

interface Main
{
    public function foo();
}

class Sub implements Main
{
    public function bar()
    {
        echo 'bar';
    }
}

$sub = new Sub;
$sub->bar(); // bar

interface 是規範 class 一定要有對應的 function 宣告,所以上面的例子退吐出下列的錯誤訊息。

Fatal error: Class Sub contains 1 abstract method and must therefore be declared abstract or implement the remaining methods

我們只要宣告一個同等名稱的 function 即可。

<?php

interface Main
{
    public function foo();
}

class Sub implements Main
{
    public function foo()
    {
    }

    public function bar()
    {
        echo 'bar';
    }
}

$sub = new Sub;
$sub->bar(); // bar

interface 本身是不可以下功能的,所以通常設計來當作一種使用規範。

abstract

<?php

abstract class Main
{
    abstract public function foobar();

    public function foo() {
        echo 'foo';
    }
}

class Sub extends Main
{
    public function bar()
    {
        echo 'bar';
    }
}

$sub = new Sub;
$sub->foo(); // foo
$sub->bar(); // bar

abstract 等於 basic 用法跟 interface 用法的集合,所以上述的內容會吐出錯誤訊息。

Fatal error: Class Sub contains 1 abstract method and must therefore be declared abstract or implement the remaining methods

此時我們要在 Sub 加上對應的 function name。

<?php

abstract class Main
{
    abstract public function foobar();

    public function foo() {
        echo 'foo';
    }
}

class Sub extends Main
{
    public function foobar()
    {
    }

    public function bar()
    {
        echo 'bar';
    }
}

$sub = new Sub;
$sub->foo(); // foo
$sub->bar(); // bar

traits

<?php

trait Main
{
    public function foo() {
        echo 'foo';
    }
}

class Sub
{
    use Main;

    public function bar()
    {
        echo 'bar';
    }
}

$sub = new Sub;
$sub->foo(); // foo
$sub->bar(); // bar

trait 是一個有趣的東西,他可以透過 use 的方式直接調用 class,彈性無比的大,但確切的使用時機目前我還不清楚。

大亂鬥

<?php

abstract class Cool
{
    abstract public function foo3();

    public function foo2()
    {
        echo 'foo2';
    }
}

interface Happy
{
    public function foo4();
}

interface Smile
{
    public function foo5();
}

trait Main
{
    public function foo() {
        echo 'foo';
    }
}

class Sub extends Cool implements Happy, Smile
{
    use Main;

    public function bar()
    {
        echo 'bar';
    }

    public function foo3()
    {
    }

    public function foo4()
    {
    }

    public function foo5()
    {
    }
}

$sub = new Sub;
$sub->foo(); // foo
$sub->bar(); // bar
$sub->foo2(); // foo2

沒有留言: