zephir-(9)類和物件2
#zephir-(9)類和物件2#
##前言## 先在這裡感謝各位zephir開源技術提供者
zephir全面使用物件程式設計,這就是為什麼拓展的使用方式只能是方法和類,你也將看到,大部分的時間,執行時錯誤引發異常,而不是致命錯誤或警告。今天講一步步講解zephir類方法變數範圍等等的使用,希望大家喜歡.
注:筆者水平有限,說的不正確的地方希望大家多多指正,一同交流技術
附上:
喵了個咪的部落格:w-blog.cn
zephir官網地址:http://zephir-lang.com/
github地址:https://github.com/phalcon/zephir
##嚴格/靈活的引數的資料型別##
在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); // 失敗
然而,傳遞一個錯誤的型別可能會經常導致錯誤,不使用特定的API會產生意想不到的效果。您可以通過設定一個嚴格的資料型別的引數禁止自動轉換:
public function filterText(string! text, boolean escape=false)
{
//...
}
現在,大多數錯誤型別的呼叫會導致一個異常由於無效資料型別傳遞:
<?php $o->filterText(1111, 1); // 失敗 $o->filterText("some text", null); // OK $o->filterText(null, true); // 失敗 $o->filterText("some text", true); // OK $o->filterText(array(1, 2, 3), true); // 失敗
通過指定什麼引數嚴格,什麼是靈活的,開發人員可以做到真正想要的定製行為。
##只讀引數##
使用關鍵字“const”可以引數標記為只讀的,內部引數標註該屬性不能修改方法:
namespace App;
class MyClass
{
// "a" 是一個常量
public function getSomeData(const string a)
{
// 這將丟擲一個編譯器異常
let a = "hello";
}
}
當一個引數被宣告為只讀的時候,編譯器可以使安全假設和對這些變數進行進一步的優化。
##類的屬性##
類成員變數被稱為“屬性”。預設情況下,他們作為PHP的屬性。屬性實現通常使用可見性修飾符,在Zephir中可見性修飾符是強制性的:
namespace Test;
class MyClass
{
public myProperty1;
protected myProperty2;
private myProperty3;
}
在類方法訪問非靜態屬性可以通過使用->(物件操作符):這個->屬性:
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 'AppMyClass' 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 = "myProperty";
echo this->{someProperty}
##類的常量##
類是保持不變的,一旦擴充套件被編譯的類常量就已經確認下來了。
namespace Test;
class MyClass
{
const MYCONSTANT1 = false;
const MYCONSTANT2 = 1.0;
}
類常量可以使用類名稱和訪問靜態操作符(::):
namespace Test;
class MyClass
{
const MYCONSTANT1 = false;
const MYCONSTANT2 = 1.0;
public function someMethod()
{
return MyClass::MYCONSTANT1;
}
}
##呼叫方法##
方法可以被使用在PHP物件操作符(- >)呼叫:
namespace Test;
class MyClass
{
protected function _someHiddenMethod(a, b)
{
return a - b;
}
public function someMethod(c, d)
{
return this->_someHiddenMethod(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}();
}
}
##引數的命名##
ZEPHIR支援名稱或關鍵字引數呼叫方法的引數。如果你想通過以任意順序引數,記錄引數的含義或以更優雅的方式指定引數命名引數可以是有用的。
考慮下面的例子,一個名為“Image”類有接收四個引數的方法:
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
當編譯器在編譯時不知道這些引數的正確順序 他們必須解決在執行時,在這種情況下,可能會有一個最小附加額外的開銷:
let i = new {someClass}(); i->chop(y:30, x: 20);
##總結##
那麼到這裡關於zephir類方法相關的知識就已經結束了,那麼從下節開始將講解內建的一些方法函式的使用,已經流程控制語句,希望大家喜歡!
應為確實zephir的類方法這一塊的類容比較多,筆者在這裡分成兩個小節進行說明,多謝大家的支援!
注:筆者能力有限有說的不對的地方希望大家能夠指出,也希望多多交流!
zephir技術交流:246348908 歡迎大家的加入!
感謝zephir開發人員: