内容简介:[ PHP 内核与扩展开发系列] 类与面向对象:接口实现与类的继承
定义 接口
定义一个接口还是很方便的,我先给出一个 PHP 语言中的实现:
<?php
interface i_myinterface
{
public function hello();
}
其在扩展中的实现是这样的:
zend_class_entry *i_myinterface_ce;
static zend_function_entry i_myinterface_method[] = {
ZEND_ABSTRACT_ME(i_myinterface, hello, NULL) //注意这里的 null 指的是arginfo
{NULL,NULL,NULL}
};
ZEND_MINIT_FUNCTION(test)
{
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "i_myinterface", i_myinterface_method);
i_myinterface_ce = zend_register_internal_interface(&ce TSRMLS_CC);
return SUCCESS;
}
我们使用 ZEND_ABSTRACT_ME()
宏函数来为这个接口添加函数,它的作用是声明一个类似虚函数的东西,不用实现。也就是说我们不用为其添加 ZEND_METHOD(i_myinterface,hello){...}
的实现。但是这个宏函数只能为我们实现 public 类型方法的声明,如果有其它特殊需要,需要使用 ZEND_FENTRY()
宏函数来实现,因为 ZEND_ABSTRACT_ME
只不过是后者的一种封装。
下面我们在 PHP 语言中使用这个接口:
<?php
class sample implements i_myinterface
{
public $name = "hello world!";
public function hello()
{
echo $this->name."\n";
}
}
$obj = new sample();
$obj->hello();
类的继承与接口实现
在定义一个类时往往会使其继承某个父类或者实现某个接口,在扩展中实现这个功能非常方便。下面我先给出 PHP 语言中对应的实现代码:
<?php
interface i_myinterface
{
public function hello();
}
class parent_class implements i_myinterface
{
public function hello()
{
echo "Good Morning!\n";
}
}
final class sub_class extends parent_class
{
public function call_hello()
{
$this->hello();
}
}
上面的代码我们已经非常熟悉了,它们在 PHP 扩展中的实现是这样的:
// 三个zend_class_entry
zend_class_entry *i_myinterface_ce, *parent_class_ce, *sub_class_ce;
// parent_class的hello方法
ZEND_METHOD(parent_class, hello)
{
php_printf("hello world!\n");
}
// sub_class的call_hello方法
ZEND_METHOD(sub_class, call_hello)
{
//这里涉及到如何调用对象的方法,详细内容下一章叙述
zval *this_zval;
this_zval = getThis();
zend_call_method_with_0_params(&this_zval, sub_class_ce, NULL, "hello", NULL);
}
// 各自的zend_function_entry
static zend_function_entry i_myinterface_method[] = {
ZEND_ABSTRACT_ME(i_myinterface, hello, NULL)
{NULL,NULL,NULL}
};
static zend_function_entry parent_class_method[] = {
ZEND_ME(parent_class, hello, NULL, ZEND_ACC_PUBLIC)
{NULL,NULL,NULL}
};
static zend_function_entry sub_class_method[]={
ZEND_ME(sub_class, call_hello, NULL, ZEND_ACC_PUBLIC)
{NULL,NULL,NULL}
};
ZEND_MINIT_FUNCTION(test)
{
zend_class_entry s_ce, p_ce, i_ce;
INIT_CLASS_ENTRY(i_ce, "i_myinterface", i_myinterface_method);
i_myinterface_ce = zend_register_internal_interface(&i_ce TSRMLS_CC);
//定义父类,最后使用zend_class_implements函数声明它实现的接口
INIT_CLASS_ENTRY(p_ce, "parent_class", parent_class_method);
parent_class_ce = zend_register_internal_class(&p_ce TSRMLS_CC);
zend_class_implements(parent_class_ce TSRMLS_CC, 1, i_myinterface_ce);
// 定义子类,使用zend_register_internal_class_ex函数
INIT_CLASS_ENTRY(s_ce, "sub_class", sub_class_method);
sub_class_ce = zend_register_internal_class_ex(&s_ce, parent_class_ce, "parent_class" TSRMLS_CC);
//注意:ZEND_ACC_FINAL是用来修饰方法的,而ZEND_ACC_FINAL_CLASS是用来修饰类的
sub_class_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
return SUCCESS;
}
这样,当我们在 PHP 语言中进行如下操作时,便会得到预期的输出:
<?php
$obj = new sub_class();
$obj->call_hello();
输出内容如下:
hello world!
这里的 ZEND_ABSTRACT_ME()
宏函数比较特殊,它会声明一个 abstract public 类型的函数,这个函数不需要我们实现,因此也就不需要相应的 ZEND_METHOD(i_myinterface,hello){...}
的实现。一般来说,一个接口是不能设计出非 public 类型的方法的,因为接口暴露给使用者的都应该是一些公开的信息。不过如果你非要这么设计,那也不是办不到,只是别用 ZEND_ABSTRACT_ME()
宏函数就行了,而是用它的底层实现 ZEND_FN()
宏函数:
//它可以对应<?php ...public static function apply_request();...的接口方法声明
static zend_function_entry i_myinterface[]=
{
ZEND_FENTRY(apply_request, NULL, NULL, ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_PUBLIC)
{NULL,NULL,NULL}
};
这样,只要掩码中有 ZEND_ACC_ABSTRACT
,便代表是一个不需要具体实现的方法。 ZEND_FENTRY
其实是 ZEND_ME
和 ZEND_FE
的最终实现,现在我们把这一组宏罗列一次展开,供你参考使用:
#define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
#define ZEND_FN(name) zif_##name
#define ZEND_MN(name) zim_##name
#define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
#define ZEND_ME(classname, name, arg_info, flags) ZEND_FENTRY(name, ZEND_MN(classname##_##name), arg_info, flags)
以上所述就是小编给大家介绍的《[ PHP 内核与扩展开发系列] 类与面向对象:接口实现与类的继承》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 028.Python面向对象继承(单继承,多继承,super,菱形继承)
- PHP类继承、接口继承关系概述
- 面向对象:理解 Python 类的单继承与多继承
- java入门第二季--继承--java中的继承初始化顺序
- 前端基本功(七):javascript中的继承(原型、原型链、继承的实现方式)
- 组合还是继承,这是一个问题?——由模式谈面向对象的原则之多用组合、少用继承
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
XML Hacks
Michael Fitzgerald / O'Reilly Media, Inc. / 2004-07-27 / USD 24.95
Developers and system administrators alike are uncovering the true power of XML, the Extensible Markup Language that enables data to be sent over the Internet from one computer platform to another or ......一起来看看 《XML Hacks》 这本书的介绍吧!