原文:Zephir类和对象 #类和对象 Zephir能够优化面向对象编程,通过使用Zephir能够让你把方法和类写入到PHP扩展中,从而避免常见的运行致命错误和警告,取而代之的是编译错误。 ##类 每一个Zephir文件必须实现一个且只能是一个类或者接口。Zephir的类接口跟PHP的类结构非常相似。
namespace Test;
/**
* This is a sample class
*/
class MyClass
{
}
##类定义 以下类的限定是被允许的: ###Final:这个类不允许被继承
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来定义方法的访问权限。
namespace Test;
class MyClass
{
public function myPublicMethod()
{
// ...
}
protected function myProtectedMethod()
{
// ...
}
private function myPrivateMethod()
{
// ...
}
}
方法中可以接受必选参数和可选参数,可以设定参数的默认值来实现可选参数
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时是空字符串
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
}
##支持的权限控制修饰符
- 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;
}
}
你也可以通过以下代码实现相同功能
namespace App;
class MyClass
{
protected myProperty {
set, get, toString
};
protected someProperty = 10 {
set, get
};
}
当编译器在编译生成时会自动生成相关属性的设置和get方法,但是你不用一个一个的去编写。降低编写难度。 #返回类型的声明 方法和接口可以声明返回类型,如下:
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();
}
}
一个方法也可以拥有多个返回类型,当定义了多个返回类型时,请使用|符号来分割各个类型
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);
今天翻译完成...
来源:oschina
链接:https://my.oschina.net/u/1045414/blog/631242