有关spModel类的继承问题

#1 stalker

昨天我自建了一个继承自spModel的数据库类   重写了update方法  主要意图是增加一个字段操作符  如某字段自增或自减  只添加了2、3行代码  但是调试的时候却总是返回false  经过debug发现  原因竟是因为没有权限调用基类的__prepara_format方法   把此方法的作用域由private修改为protected之后问题解决  但是不知道这样做会不会有什么风险?

2013-04-26 11:40:11

#2 jake

__prepera_format方法是内部方法,之所以是private是认为继承类不需要使用到它。换句话说,用到它的方法,都是不能改变逻辑的。

估计你是“重写”了update,而不是“覆盖”。继承是覆盖父类,就是在不改变原父类逻辑的前提下,在继承的继承上增加功能。但重写的意思是完全抛弃父类。

简单来说,覆盖是允许的,会调用parent::update,而重写,就不会,也是建议不要做的事情。

2013-04-26 11:49:11

#3 coolhpy

只是自增或自减某个字段的话,可以使用incrField和decrField两个方法啊,都是三个参数。
第一个:执行条件,同update的第一个参数(array/string),必选
第二个:要递增或递减的字段(string),必选
第三个:递增或递减多少(integer),可选,默认:1

Jake真的有必要更新下手册了哦,这俩方法都没写,但是程序中是有的。

2013-04-26 14:11:52

#4 jake

coolhpy 发表于 2013-4-26 14:11
第三个:递增或递减多少(integer),可选,默认:1

Jake真的有必要更新下手册了哦,这俩方法都没写,但是程序中是有的。 ...
手册里面有的哦~~~ http://www.speedphp.com/thread-3878-1-8.html

incrField.jpg

2013-04-26 16:58:03

#5 coolhpy

jake 发表于 2013-4-26 16:58
手册里面有的哦~~~ http://www.speedphp.com/thread-3878-1-8.html
原来在这个位置啊,,我一直在API参考--类库--spModel模型类里面找。。

2013-04-27 09:50:56

#6 stalker

我是重写了update方法   因为我要实现的效果是自增/减操作符可以混在普通的update数组里
类似
$this->update(array('id'=>1), array('name'=>'abc', 'logincount'=>'++'))
而这个是incrField/decrField实现不了的

2013-04-27 20:26:56

#7 jake

stalker 发表于 2013-4-27 20:26
我是重写了update方法   因为我要实现的效果是自增/减操作符可以混在普通的update数组里
类似
所以说是为什么这种写法是不建议的,因为你改变了父类update方法的第二个参数的意义。

这里肯定就不会再调用parent::update方法。

面向对象继承的意义,就是不能改变原有父类方法的意义,包括参数的意义。只能是“扩展”,不能是“改变”。

这个问题是出在,后面使用这个方法的人,就弄不清楚这个参数到底是什么意思了。

一般我们做这种“改变”型的新功能,会用到“组合”,而不是“继承覆盖”。比如说新加个方法叫updateAndIncrease()来做到这个功能。


2013-04-27 21:37:28

#8 stalker

jake 发表于 2013-4-27 21:37
所以说是为什么这种写法是不建议的,因为你改变了父类update方法的第二个参数的意义。

这里肯定就不会再 ...
可是使用不同的方法名就可以调用父类的私有方法了吗?

2013-05-02 18:39:38

#9 stalker

不知道不同的语言有多大的区别   不过我学C的时候看到的例子都是子类使用相同的方法实现与父类有所差别的作用   这实现了面向对象主要特征之一“多态”   也允许利用索引器实现各种各样不同的引用方式、允许同样的方法在父类和子类中实现不尽相同的功能、允许同样的方法在一个类中或者子类和父类中具有不同个数、不同类型的参数  甚至可以对数学运算符+ - × / abs sin cos等进行重载而实现不同的功能  而为什么php或者说在sp里却都不允许  

2013-05-02 18:52:09

#10 coolhpy

stalker 发表于 2013-5-2 18:39
可是使用不同的方法名就可以调用父类的私有方法了吗?
私有方法当然不能调用。
jake的意思,然后另外写个方法,然后分两步来实现:第一步,把可以用来常规的字段用update来更新;第二步,把自增(自减)的字段用incrField(decrField)来实现。
要么,你就是自行去拼凑个SQL,然后用query来执行。

2013-05-02 23:38:15

#11 coolhpy

stalker 发表于 2013-5-2 18:52
不知道不同的语言有多大的区别   不过我学C的时候看到的例子都是子类使用相同的方法实现与父类有所差别的 ...
大哥,不同语言有不同语言的语法特性,不是说c里面有,php里面就一定有的!
你真要问为什么,去找写出php这种语言的人去。这不是SP的问题!

2013-05-02 23:41:15

#12 stalker

coolhpy 发表于 2013-5-2 23:41
大哥,不同语言有不同语言的语法特性,不是说c里面有,php里面就一定有的!
你真要问为什么,去找写出ph ...
我并不是说哪个语法别的语言支持而php不支持   而是面向对象编程相对面向过程编程的优势:低耦合度、多态性  php在这方面明明和所有语言一样都支持  为什么在这里都不支持 或者说 不提倡?  不希望改动你的框架可以理解   但是别人在子类里自己重写一个同名的方法也不允许?  框架设计了不允许把未声明的成员变量变成控制器的成员变量而是直接赋值为视图的成员变量   别人修改为把未声明的成员变量变成控制器的成员变量在输出视图之前履行”变量“的功能就不允许?  

2013-05-03 00:56:09

#13 jake

stalker 发表于 2013-5-3 00:56
我并不是说哪个语法别的语言支持而php不支持   而是面向对象编程相对面向过程编程的优势:低耦合度、多态 ...
不是说不允许,语言是自由的,爱怎么写就怎么写。

上面说的,只是垮语言层面的一些理念,比如说面向对象的一些准则。

别说什么c甚至可以做运算符重载,要明白不是可以做什么事就一定要去做。

举个简单例子,private是面向对象的一个限制作用的语法,但是你直接就可以改成public,因为代码是自由的,你想怎么写就怎么写,没人能说什么不允许。

我们做sp也好,论坛回答问题也好,只是想传递一些正确的,开发者都认可,遵循了有好处的开发理念,所以我们会说怎么样写才是更符合传统规则。

如果不喜欢听,或者不认同,可以自行其道,谁也管不着。

------

其实我更希望你去改框架,这样你也可以达到你想要的,我也可以继续提供一些好的开发理念,各不相关。这也是开源的意义之一。

2013-05-03 08:11:13

#14 jake

coolhpy 发表于 2013-5-2 23:41
大哥,不同语言有不同语言的语法特性,不是说c里面有,php里面就一定有的!
你真要问为什么,去找写出ph ...
没必要说太多,连改变参数意义都觉得理所当然的人,连多态都被那样曲解的人,是不需要争论的。

总会有大条道理,只是连最基本的理念都不理解而已。

所以,一句话就行:我们只和适当的人说我们多年经验总结出来的适当的方法,但是楼上那位并非恰当的人,所以他的程序爱怎么写怎么写。

2013-05-03 08:19:58

#15 coolhpy

stalker 发表于 2013-5-3 00:56
我并不是说哪个语法别的语言支持而php不支持   而是面向对象编程相对面向过程编程的优势:低耦合度、多态 ...
只能说,你在这问题上,太过纠结了。

2013-05-03 09:17:54