Zephir 文檔翻譯-類和對象

原文:Zephir類和對象 #類和對象 Zephir可以優化面向對象編程,經過使用Zephir可以讓你把方法和類寫入到PHP擴展中,從而避免常見的運行致命錯誤和警告,取而代之的是編譯錯誤。 ##類 每個Zephir文件必須實現一個且只能是一個類或者接口。Zephir的類接口跟PHP的類結構很是類似。php

namespace Test;

/**
 * This is a sample class
 */
class MyClass
{

}

##類定義 如下類的限定是被容許的: ###Final:這個類不容許被繼承html

namespace Test;

/**
 * This class cannot be extended by another class
 */
final class MyClass
{

}

###Abstract:該類禁止被實例化編程

namespace Test;

/**
 * This class cannot be instantiated
 */
abstract class MyClass
{

}

##編寫方法 同PHP中同樣,使用function關鍵字來定義類的方法,能夠經過private、public、protected來定義方法的訪問權限。app

namespace Test;

class MyClass
{

    public function myPublicMethod()
    {
        // ...
    }

    protected function myProtectedMethod()
    {
        // ...
    }

    private function myPrivateMethod()
    {
        // ...
    }
}

方法中能夠接受必選參數和可選參數,能夠設定參數的默認值來實現可選參數ide

namespace Test;

class MyClass
{

    /**
     * All parameters are required
     */
    public function doSum1(a, b)
    {
        return a + b;
    }

    /**
     * Only 'a' is required, 'b' is optional and it has a default value
     */
    public function doSum2(a, b = 3)
    {
        return a + b;
    }

    /**
     * Both parameters are optional
     */
    public function doSum3(a = 1, b = 2)
    {
        return a + b;
    }

    /**
     * Parameters are required and their values must be integer
     */
    public function doSum4(int a, int b)
    {
        return a + b;
    }

    /**
     * Static typed with default values
     */
    public function doSum4(int a = 4, int b = 2)
    {
        return a + b;
    }
}

##可選的null參數 Zephir確保方法參數會被賦值,經過null默認值會在運行時轉化到目標類型。如:null轉化到int時爲0,轉換到boolean時是false,轉化到string時是空字符串oop

public function foo(int a = null)
{
    echo a; // if "a" is not passed it prints 0
}

public function foo(boolean a = null)
{
    echo a; // if "a" is not passed it prints false
}

public function foo(string a = null)
{
    echo a; // if "a" is not passed it prints an empty string
}

public function foo(array a = null)
{
    var_dump(a); // if "a" is not passed it prints an empty array
}

##支持的權限控制修飾符優化

  1. Pubic:被標記了pubic的方法,能夠被任何類調用 2.Protected:標記了protected的方法。。。 3.Private: ##支持的方法修飾符 1.Final: If a method has this modifier it cannot be overriden 2.Deprecated: Methods marked as 「deprecated」 throwing an E_DEPRECATED error when they are called. ##Getter/Setter便捷寫法 就像使用C#同樣,你能夠在Zephir中使用get/set/toString標籤,這個特性容許你輕鬆的爲類屬性建立獲取和設置方法。
namespace Test;

class MyClass
{
    protected myProperty;

    protected someProperty = 10;

    public function setMyProperty(myProperty)
    {
        this->myProperty = myProperty;
    }

    public function getMyProperty()
    {
        return this->myProperty;
    }

    public function setSomeProperty(someProperty)
    {
        this->someProperty = someProperty;
    }

    public function getSomeProperty()
    {
        return this->someProperty;
    }

    public function __toString()
    {
        return this->myProperty;
    }

 }

你也能夠經過如下代碼實現相同功能ui

namespace App;

class MyClass
{
    protected myProperty {
        set, get, toString
    };

    protected someProperty = 10 {
        set, get
    };

}

當編譯器在編譯生成時會自動生成相關屬性的設置和get方法,可是你不用一個一個的去編寫。下降編寫難度。 #返回類型的聲明 方法和接口能夠聲明返回類型,以下:this

namespace App;

class MyClass
{
    public function getSomeData() -> string
    {
        // this will throw a compiler exception
        // since the returned value (boolean) does not match
        // the expected returned type string
        return false;
    }

    public function getSomeOther() -> <App\MyInterface>
    {
        // this will throw a compiler exception
        // if the returned object does not implement
        // the expected interface App\MyInterface
        return new App\MyObject;
    }

    public function process()
    {
        var myObject;

        // the type-hint will tell the compiler that
        // myObject is an instance of a class
        // that implement App\MyInterface
        let myObject = this->getSomeOther();

        // the compiler will check if App\MyInterface
        // implements a method called "someMethod"
        echo myObject->someMethod();
    }

}

一個方法也能夠擁有多個返回類型,當定義了多個返回類型時,請使用|符號來分割各個類型spa

namespace App;

class MyClass
{
    public function getSomeData(a) -> string | bool
    {
        if a == false {
            return false;
        }
        return "error";
    }
}

##返回類型 Void 若是一個方法的返回值被聲明爲void,則表示該方法不容許返回任何數據。

public function setConnection(connection) -> void
{
    let this->_connection = connection;
}

設置void返回值聲明後,若是有調用錯誤會產生編譯錯誤而不是運行錯誤,避免隱性的漏洞。

let myDb = db->setConnection(connection);
myDb->execute("SELECT * FROM robots"); // this will produce an exception

##靜態/動態 的參數類型 在Zephir中能夠特別的指定變量類型,默認狀況下變量類型是動態的,若是指定了變量類型,Zephir會嘗試把傳入參數轉化成指定的類型。

public function filterText(string text, boolean escape=false)
{
    //...
}

以上方法在執行時的結果:

<?php

$o->filterText(1111, 1); // OK
$o->filterText("some text", null); // OK
$o->filterText(null, true); // OK
$o->filterText("some text", true); // OK
$o->filterText(array(1, 2, 3), true); // FAIL

如今,大多數狀況下傳入一個錯誤類型的參數會拋出一個異常

<?php

$o->filterText(1111, 1); // FAIL
$o->filterText("some text", null); // OK
$o->filterText(null, true); // FAIL
$o->filterText("some text", true); // OK
$o->filterText(array(1, 2, 3), true); // FAIL

儘量的定義參數的類型有助於程序編寫。 ##只讀變量 經過使用const關鍵字聲明能夠標明一個變量爲只讀變量,這種變量將不被容許在方法中被修改。

namespace App;

class MyClass
{
    // "a" is read-only
    public function getSomeData(const string a)
    {
        // this will throw a compiler exception
        let a = "hello";
    }
}

當一個變量被設定爲不可修改時,編譯器會對這個變量作最大化的優化 ##實現類的屬性 類中的變量稱之爲屬性(properties)。Zephir類屬性能夠映射到PHP類中,二者對於屬性的控制方法一致。

namespace App;

class MyClass
{
    // "a" is read-only
    public function getSomeData(const string a)
    {
        // this will throw a compiler exception
        let a = "hello";
    }
}

類中的非靜態屬性能夠經過->來修改和讀取值。

namespace Test;

class MyClass
{

    protected myProperty;

    public function setMyProperty(var myProperty)
    {
        let this->myProperty = myProperty;
    }

    public function getMyProperty()
    {
        return this->myProperty;
    }
}

屬性能夠有默認值,可是默認值必須是靜態的且不依賴與運行時的變量、參數

namespace Test;

class MyClass
{

    protected myProperty1 = null;
    protected myProperty2 = false;
    protected myProperty3 = 2.0;
    protected myProperty4 = 5;
    protected myProperty5 = "my value";
}

##更新類的屬性 屬性的值能夠經過->引用來更新

let this->myProperty = 100;

Zephir會在編譯時檢查屬性是否存在,若是被操做的屬性不存在則會拋出以下錯誤:

CompilerException: Property '_optionsx' is not defined on class 'App\MyClass' in /Users/scott/utils/app/myclass.zep on line 62

      this->_optionsx = options;
      ------------^

若是你想動態的建立一個屬性並複製的話,你可使用以下的方法去實現:

let this->{"myProperty"} = 100;

你也能夠經過使用變量去更新對應名稱的屬性值

let someProperty = "myProperty";
let this->{someProperty} = 100;

##讀取類的屬性 經過使用->來讀取

echo this->myProperty;

當須要更新屬性值時,能夠動態的讀取和設置值

//避免編譯器檢查屬性是否存在,動態的建立屬性
echo this->{"myProperty"}
//經過變量名稱來讀取屬性
let someProperty="mProperty";
echo this->{someProperty};

##類常量 能夠定義類中的屬性爲常量,避免被修改。這種定義容許在php中直接使用

namespace Test;
class MyClass{
    const MYCONSTANT1=false;
    const MYCONSTANT2=1.0;
}

類屬性常量能夠經過靜態屬性引用方式來讀取(::)

namespace Test;
class MyClass{
    const MYCONSTANT1=false;
    public function someMethod(){
        return MyClass::MYCONSTANT1;
    }
}

##調用類的方法 調用Zephir的方法可使用和PHP類方法的調用同樣的方式->

namespace Test;
class MyClass{
    protected function a(a,b){
        return a-b;
    }
    public function b(c,d){
        return this->a(c,d);
    }
}

靜態方法必須使用靜態方法的操做符::

namespace Test;

class MyClass
{

    protected static function _someHiddenMethod(a, b)
    {
        return a - b;
    }

    public static function someMethod(c, d)
    {
        return self::_someHiddenMethod(c, d);
    }
}

你也能夠動態的訪問某個類的方法:

namespace Test;

class MyClass
{
    protected adapter;

    public function setAdapter(var adapter)
    {
        let this->adapter = adapter;
    }

    public function someMethod(var methodName)
    {
        return this->adapter->{methodName}();
    }
}

##經過變量名來傳參(高端..) 咱們先定義以下的一個類,讓咱們來看看有什麼神奇的使用方法

namespace Test;

class Image
{
    public function chop(width = 600, height = 400, x = 0, y = 0)
    {
        //...
    }
}

常規狀況下咱們是這樣去調用方法的

i->chop(100); // width=100, height=400, x=0, y=0
i->chop(100, 50, 10, 20); // width=100, height=50, x=10, y=20

使用變量名傳參的狀況下你能夠這樣寫

i->chop(width: 100); // width=100, height=400, x=0, y=0
i->chop(height: 200); // width=600, height=200, x=0, y=0
i->chop(height: 200, width: 100); // width=100, height=200, x=0, y=0
i->chop(x: 20, y: 30); // width=600, height=400, x=20, y=30

若是Zephir在編譯時不知道變量順序時,必須在運行時指定。

let i = new {someClass}();
i->chop(y:30, x: 20);

今天翻譯完成...

相關文章
相關標籤/搜索