Zephir 文档翻译-类和对象

不问归期 提交于 2019-12-03 07:56:58

原文: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
}

##支持的权限控制修饰符

  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;
    }

 }

你也可以通过以下代码实现相同功能

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);

今天翻译完成...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!