淺談PHP源碼二十九:關於介面的繼承

來源:互聯網
上載者:User
這篇文章主要介紹了關於淺談PHP源碼二十九:關於介面的繼承,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

淺談PHP源碼二十九:關於介面的繼承

在之前有看過PHP源碼中類的繼承,今天我們看下PHP中的介面繼承是如何?的。
同樣我們從CachingIterator類開始尋找介面的繼承實現。
CachingIterator extends IteratorIterator implements OuterIterator , Traversable , Iterator , ArrayAccess , Countable

  /* ArrayAccess介面的繼承實現 */REGISTER_SPL_IMPLEMENTS(CachingIterator, ArrayAccess); //    ext/spl/spl_functions.h 41行#define REGISTER_SPL_IMPLEMENTS(class_name, interface_name) \zend_class_implements(spl_ce_ ## class_name TSRMLS_CC, 1, spl_ce_ ## interface_name); //zend/zend_API.c 2218行ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int num_interfaces, ...) /* {{{ */{zend_class_entry *interface_entry;va_list interface_list;va_start(interface_list, num_interfaces); while (num_interfaces--) {interface_entry = va_arg(interface_list, zend_class_entry *);zend_do_implement_interface(class_entry, interface_entry TSRMLS_CC);} va_end(interface_list);}/* }}} */   //zend/zend_complie.c 2887行ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) /* {{{ */{zend_uint i, ignore = 0;zend_uint current_iface_num = ce->num_interfaces;zend_uint parent_iface_num  = ce->parent ? ce->parent->num_interfaces : 0; for (i = 0; i < ce->num_interfaces; i++) {if (ce->interfaces[i] == NULL) {memmove(ce->interfaces + i, ce->interfaces + i + 1, sizeof(zend_class_entry*) * (--ce->num_interfaces - i));i--;} else if (ce->interfaces[i] == iface) {/* 已存在此介面 */if (i < parent_iface_num) {ignore = 1;} else {zend_error(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ce->name, iface->name);}}}if (!ignore) {if (ce->num_interfaces >= current_iface_num) {if (ce->type == ZEND_INTERNAL_CLASS) {ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));} else {ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));}}ce->interfaces[ce->num_interfaces++] = iface;//介面數加1,將介面加入介面列表中 /* 合并介面中的常量列表和方法列表 */zend_hash_merge_ex(&ce->constants_table, &iface->constants_table, (copy_ctor_func_t) zval_add_ref, sizeof(zval *), (merge_checker_func_t) do_inherit_constant_check, iface);zend_hash_merge_ex(&ce->function_table, &iface->function_table, (copy_ctor_func_t) do_inherit_method, sizeof(zend_function), (merge_checker_func_t) do_inherit_method_check, ce); do_implement_interface(ce, iface TSRMLS_CC);zend_do_inherit_interfaces(ce, iface TSRMLS_CC);}}

從zend_do_implement_interface函數的合并介面中的常量列表和方法列表操作,我們可以猜想這也許是介面中不能有變數可以有常量的原因之一吧
在介面繼承的過程中有對當前類的介面中是否存在同樣介面的判斷操作,如果已經存在了同樣的介面,則此介面將不會繼承。
如下所示php代碼:

<?phpinterface FooInterface {public function method1();} class Base implements FooInterface {public function method1() {echo 'ss';}} class Foo extends Base implements FooInterface { } $foo = new Foo();$foo->method1();

以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.