jdon 解惑授道,企业信息化解决之道
 

热点Tag: AOP cache DDD EJB 集群 设计模式 Hibernate IOC JiveJdon OO RBAC Spring Struts

Jdon框架演示

JiveJdon3.0
源码下载

GoF设计模式

在线教程

社区精彩讨论












我来讨论一下纯理论的老问题.长方形和正方形的继承关系.

作者:siberian 发表时间:2007年03月01日 19:50 回复此消息回复

原贴网址: http://www.jdon.com/jivejdon/thread/31041.html

类的定义中,大家一直争吵不休的就是正方形和长方形的关系.所说,正方形不是长方形的子类,因为它违反了长方形的行为.

然而计算机世界应当是当前世界在计算机中的映射.那么我们来考察长方形和正方形的定义,长方形也就是矩形:为四个内角相等的平行四边形。正方形,是平行四边形;. 有一个角是直角;. 有一组邻边相等。

可是OO对象中,却不能是继承关系。为什么?因为里面的概念已经被偷换了,我们所定义的只是我们在某方面运用到的长方形和正方形。它的定义是全新的,包括了里面所有的数据和所有的方法。不再是我们在数学中定义的长方形和正方形。

也就是说我们的OO定义的类,和现实世界不能完全映射上,只是反映其中我们想要得部分。它的定义是不完整的,过于简单,无法反映数据和数据间的关系,契约太过强硬,只要是所用到的行为子类都要遵守。于是我们很着急,这违反了OO初衷。哲学上告诉我们片面的抽象扩大化,会走到我们所期望的反面。可以说这就是一个例子,原本现实分类中很明显的继承关系,反而到了OO中,不成立了,或者说成为一个问题。不象现实中那样清晰。

我们为了简化而把事情搞复杂了。也许我们在纯粹的程序世界里面还可以不大在意这件事,按照自己定义的就可以了。但是我们要做需求分析时,这就成为大问题。那是必须和现实世界映射上的,任何的扭曲都会带来很多的麻烦。现在工作中我们的麻烦确实很多,原本清晰可见的关系,我们要重新调理。于是我们开始思考。

我们要用现实世界中的关系来指导OO设计,于是什么LSP,DBC都冒出来告诉我们怎么做。可是还是不行。

下一篇讨论这个问题在做用例分析时可能造成的泥潭。如何回避。

在我的blog:http://yingyiyy.blog.163.com/有后续文章。讲谈到这在工作中的实际意义。

re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月01日 20:24 回复
Coolyu0916 发表文章: 196/ 注册时间: 2007年04月23日 11:29
我不知道谁讨论说正方形不是长方形的子类的
你能把文章给我转贴一下么??
我觉得既然从数学定义上是,实际设计也一定是。
要不然OO的设计就是个错误

re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月01日 21:53 回复
checkcode 发表文章: 8/ 注册时间: 2007年02月22日 16:02
我觉得可能是这个问题,当
正方形继承长方形的时候,可以使正方形is a长方形
但是无法保证,x形继承正方形时,使x形既具有正方形的行为又具有长方形的行为

re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月01日 22:11 回复
Coolyu0916 发表文章: 196/ 注册时间: 2007年04月23日 11:29
没有明白楼上的意思
x继承了正方形必然具备正方形的特性
所谓继承的意思就是 XX就是XX
男人就是人 ,女人是人
人生孩子是错的
必须是女人生孩子
楼主是说 老女人不具备生孩子的方法么,他具备这个方法,但是返回的东西不同??
可是这在生活中也是必然的
if(age > 60) return null; 或者throw excption(“年纪太大”)
不是这样么??

re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月01日 22:48 回复
siberian 发表文章: 24/ 注册时间: 2003年07月14日 16:24
其实,这在《java编程思想》里面认为是可以成立的。只不过某些涉及父类的方法要修改。
我认为也是成立的。只不过我们从这个争论为什么会发生,会发现类定义里面类太简单,没有涉及到约束的问题。
这是要说的重点。一个事物必然要包括一个约束问题。也就是说一个类要成功映射。不是他的所有属性,方法都必须被遵守,而是只要它符合一个约束,就成立了。

re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月01日 23:30 回复
wlmouse 发表文章: 111/ 注册时间: 2006年11月09日 15:58
就好像椭圆和圆的关系一样。如果椭圆继承了圆,那么就会产生麻烦。一个圆引用指向一个椭圆的实例。那么给圆半径赋值这个操作到椭圆上面就麻烦了。圆的半径是一样的。椭圆则是不一样的,有一个长的,一个短的。该怎么办?

re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月02日 09:20 回复
Coolyu0916 发表文章: 196/ 注册时间: 2007年04月23日 11:29
to siberian
怎么可能那??
这是一个典型的约束啊
由于一个事务的状态改变而行为不同
这时候使用state模式啊
交给他的state模型来做
30岁的女人做什么
60岁的女人做什么
这些不是约束么??

to wlmouse
园是椭圆的子类
因为所有基于椭圆的数学运算都能运用在园上
我们说 园是一种特殊的椭圆 可是不能说椭圆是一种特殊的圆

re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月02日 11:15 回复
checkcode 发表文章: 8/ 注册时间: 2007年02月22日 16:02
我的意思是继承是is a的关系如果硬要用继承来描述长方形和正方形
那么实际的关系应该是is a而不是like a(正方形就是长方形吗?)
并且在考虑如果又有一个对象继承了正方形,或者继承了长方形,那他
又是什么,?现实世界不可能有这种情况,但是程序中无法保证,(除非
正方形是final)并且继承保证了当父类能用的地方子类也能用,而真要继承
是需要修改正方形内部逻辑,那么客户端调用的时候就无法保证了(难道父类和子类完全不同?)
我觉得描述正方形和长方形有3中解决方案
1,共同实现一个抽象的图形类或图形接口
2,考虑用组合,而不是继承
3,将正方形定义为final,并且保证其内部逻辑的和理性
且这三种方案的代码耦合度是逐步增加的

其实我个人一直反对用计算机完美的描述现实世界的逻辑,毕竟计算机是01的,太精确了
而现实世界不是这么回事,计算机应该是面向问题的,而不是面向逻辑(其实数学建模本
身也是面向问题的)

回复:re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月02日 13:19 回复
siberian 发表文章: 24/ 注册时间: 2003年07月14日 16:24
Coolyu0916

你明显你弄混了,类的内部问题和类与子类的关联问题.


你说30女,60女那是类的内部的.并没有表达到外面来.
而你建立了30女的类,60女的类的时候.那个约束就变成了类本身的重要的东西.

至于用状态模式也好,不用状态模式也好,不过是设计时的技巧,这些约束还是类定义本身至关重要的东西.不能随便的把它外在了.

回复:re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月02日 13:29 回复
siberian 发表文章: 24/ 注册时间: 2003年07月14日 16:24
你说的三种方法,其实在别处的讨论中已经提到.例如阎宏博士哪里就有一个大坑来讨论这问题.
而我今天说到这个问题是,是从类定义的缺乏约束的明确表达这个角度来的.毕竟清晰,无歧义的映射是OO得终极目标,任何一本讲述OO的书都会提到这一点。
我在blog将提到在实际工作中,这会造成那些问题。

re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月02日 13:33 回复
Coolyu0916 发表文章: 196/ 注册时间: 2007年04月23日 11:29
siberian , state模式并不暴露state的
我们使用的统一的方法,给用户也是统一的接口
不过在不同的state下我们引用不同的state类

用户使用的时候肯定是 woman.setAge(30); woman.procreate();
如果不给出age 就采用默认的age,这种接口不对么??
我们平时说女人生孩子,一般来说我们都是认为是年轻的妇女
但是当你告诉他是一个小女孩或者老太太的时候,调用生孩子的方法必然是一个空或者是一个异常(你告诉别人她不能生孩子,或者你跟别人说这是开玩笑)
定义接口的时候你不需要关心这些问题,因为问题只有真的发生才有意义(说女人生孩子没有意义,必须说某个女人生孩子才有意义)
你在考虑问题的时候只要让其具备功能,当你认为某个方法可能存在疑义或者可能出现问题的时候,要在子类或者方法中进行控制。

re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月02日 13:48 回复
Coolyu0916 发表文章: 196/ 注册时间: 2007年04月23日 11:29
checkcode 说实话,我一直到现在还不明白你说的意思

我们举例
如果一个对象 x 继承了正方形 比如说 (x为边大于5的正方形)我们称之为大正方吧

你要对图形计算面积,或者周长
那么你有什么不能定义那??
利用长方形的方法就可以了

子类不使用父类的实现不可以么??

回复:re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月02日 14:10 回复
siberian 发表文章: 24/ 注册时间: 2003年07月14日 16:24
toCoolyu0916
咱们在说类之间的关系.这个时候还处在从需求得到分析类的时刻,而没有到后面设计时运用某种技巧,某种模式的时候.
这个时候,那些职责是他本身的.那些职责是外在的.和state还扯不上关系。
比如说,一个女人类他有哪些行为,那些约束。那么state模式只不过是在确定了这个分析类之后的优化处理,希望把女人类某些东西外包了。

re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月02日 14:51 回复
Coolyu0916 发表文章: 196/ 注册时间: 2007年04月23日 11:29
那么我们就从需求方面走

首先我们确定了人的行为
我们不可能设计一个万能的persion class
我们只要实现有限的功能,在系统中用到的,比如eat() sleep()
现在要在性别上进行区分
这时候我们应当考虑需要怎样区分了,这个区分是为了标识还是为了实现
比如只是为了表示一个身份,一个证件,而不需要一些女人特定的动作,完全就不必需要子类,或者只是为了添加一些附加功能,也是不需要的。
这个必须从逻辑上说的通,你不能说 persion.procreate(),这个不符合逻辑,用你这个接口的人也会晕的,必须是woman.procreate(),这个时候你说不需要继承,使用组合么??或者是简单的引入一个方法么??

至于具体能不能procreate,需求的时候会告诉你,当女人在20-50的时候可能会生育,但是是20还是50是在运行中才会体现的,不是你设计接口时考虑的问题。那是到了详细设计的时候你才要关心的。


re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系. 发表: 2007年03月02日 15:32 回复
siberian 发表文章: 24/ 注册时间: 2003年07月14日 16:24
类的约束,我们创建一个Person,那么作为一个顶级类,它可以没有约束,作为一个空泛的类而存在,因为它处在抽象的顶级。
但是我们一旦有了一个子类,并且子类的相对于父类有了约束,比如长方形中长和宽可以随便数值,但是到了正方形中不行了。他们要相等,不相等的就不是正方形。这个子类很明显是靠增加约束来建立的,而不是功能的扩展。
我们在需求中挖掘出子类之后,(注意不是为了方便而创造出来的,而是现实中有了子类),就要确定它是否有了约束,还是只是扩展了。
在你举的例子中,如果生育期妇女这个概念常常出现,那么它就应该是一个类,它成立的约束条件就是年龄在20-50,性别女。不满足这个约束,这个类就不成立。它并不是一个运行时的问题,而是一个类本身的,与生俱来的东西。你可以再后来的设计中,把它放到配置文件中,但是不能回避的是,它是类本身的东西。不符合这个约束,他就不是这个类。
接口设计还要排在分析类获取的后面。至于是否方便也不是考虑的问题。我们在这个阶段是要做到完美的映射。

这个主题共有 36 回复 / 3 页 [ 1 2 3 下一页 ]
 
上一篇: (OO + 分布式计算) = 软件架构的.. 下一篇: 请问RBAC中的Permission如何..
 
查询本论坛 最热门帖子
快速发表回复:
标题
 
粗体 斜体 下划线 插入图片 插入代码 插入url链接 插入附件
内容
 
联系我们 | 关于我们 | RSS订阅 | 广告联系 | 网站地图 | 设为首页
Copyright (C) 2002-2007 Jdon.com, All Rights Reserved 版权所有 上海解道计算机技术有限公司
沪ICP备05018152号 如有意见请与我们联系 Powered by JdonFramework