magento的rewrite机制和OOP的隐藏特性

在面向对象编程中,大家都知道类之间有重载(overload)、覆盖(override)、隐藏(hide)三种关系,相信很多人对他们都已经很了解了,所以今天分析的重点也不是这些,而是magento中的rewrite机制,为什么会先提一下oop的三种特性呢,因为我觉得他们和magento的rewrite机制很相似,但相似并非相同,还是先看下代码吧,比较容易理解。

Magento发邮件时,使用的是内置的core/email_template,现在重写这个model的send function,在config.xml添加如下内容:

		<models>
			<core>
				<rewrite><email_template>Company_Mymodel_Model_Email_Template</email_template>
				</rewrite>
			</core>
		</models>

然后Company/Mymodel/Model/Email/Template.php添加如下代码:

class Company_Mymodel_Model_Email_Templateextends Mage_Core_Model_Email_Template {
        
   public function send($email, $name=null, array $variables = array()) {
             //省略,重点不在如何重写send
        }

发邮件时可以这么写:

$mailConfirm = Mage::getModel('core/email_template');

$mailConfirm->send(//参数…);

或者

$mailConfirm = Mage::getModel(mymodel /email_template');

$mailConfirm->send(//参数…);


注意调用时的区别(红色字体),一个仍然是调用内置的model,一个是重写的model,你能猜到结果是什么吗?没错,结果永远都是调用Company_Mymodel_Model_Email_Template的send函数。是不是有点像开头提到的隐藏特性,因为给人的感觉就是Company_Mymodel_Model_Email_Template的send吧core的send给隐藏了,我没有说是和覆盖相似,my god,算了还是先贴下三种特性的定义,好好体会下:

/

重载 是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。

成员函数被重载的特征
(1)相同的范围(在同一个类中); 
(2)函数名字相同; 
(3)参数不同; 
(4)virtual 关键字可有可无。

覆盖(也叫重写)是指派生类函数覆盖基类函数 是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。

 特征是
(1)不同的范围(分别位于派生类与基类); 
(2)函数名字相同; 
(3)参数相同; 
(4)基类函数必须有virtual 关键字。 

“隐藏”是指派生类的函数屏蔽了与其同名的基类函数 是指派生类中的函数把基类中相同名字的函数屏蔽掉了。隐藏与另外两个概念表面上看来很像,很难区分,其实他们的关键区别就是在多态的实现上。什么叫多态?简单地说就是一个接口,多种实现吧。

 规则如下
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。 
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆) 
3种情况怎么执行:1。重载:看参数2。隐藏:用什么就调用什么3。覆盖:调用派生类

///

因为这里的两个send 名称 参数 返回值都相同,并且基类的send没有virtual限定,所以我说是和隐藏相似。为什么只说相似呢?调用的时候,对于隐藏特性,用什么就调用什么,比如用父类的,就new 父类的对象,用子类,就new子类。但是magento的rewrite 并不是,比如上边写到的两种调用send的方法,一个是getModel的core(即父类),一个是getModel的继承类,按理说应该会调用不同的send,但结果调用的永远都是重写的send。

通过跟踪magento源码发现,在Mage_Core_Model_Config的getGroupedClassName方法中:

        $config = $this->_xml->global->{$groupType.'s'}->{$group};

        if(isset($config->rewrite->$class)) {

            $className= (string)$config->rewrite->$class;

        } else {

        //。。。。。。

        }

在Mage::getModel('core/email_template')的时候,Magento先做了一个判断,因为在前边的config里已经对coremodel email_template进行了rewrite,所以尽管调用的是core的send,执行的仍然是rewrite后的send,假如是隐藏的话,调用core的send,执行的就应该是core的send;所以假如你曾经rewrite过core的email_template,或者是有其他第三方组件rewrite过(当然前提你可能不知道或者忘记了),调试的时候,在core的email_template里改来改去,就是没反应,并且很疑惑,根据oop的隐藏规则,我也是使用Mage::getModel('core/email_template')来调用的,new的core/ email_template,怎么在core/ email_template修改就是没反应呢?因为我之前就碰到过这个问题。殊不知这里根本没有遵循OOP的隐藏原则,因为已经被magento的rewrite机制给改掉了。

 

本文将隐藏特性和rewrite机制放在一起讨论,就是希望能对二者有一个更好的理解

本文链接:http://blog.csdn.net/shangxiaoxue/article/details/7519423

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值