|
这个主题共有 36 回复 / 3 页 [
1 2 3
下一页
]
|
|
|
|
|
|
我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月01日 19:50
|
回复
|
|
类的定义中,大家一直争吵不休的就是正方形和长方形的关系.所说,正方形不是长方形的子类,因为它违反了长方形的行为.
然而计算机世界应当是当前世界在计算机中的映射.那么我们来考察长方形和正方形的定义,长方形也就是矩形:为四个内角相等的平行四边形。正方形,是平行四边形;. 有一个角是直角;. 有一组邻边相等。
可是OO对象中,却不能是继承关系。为什么?因为里面的概念已经被偷换了,我们所定义的只是我们在某方面运用到的长方形和正方形。它的定义是全新的,包括了里面所有的数据和所有的方法。不再是我们在数学中定义的长方形和正方形。
也就是说我们的OO定义的类,和现实世界不能完全映射上,只是反映其中我们想要得部分。它的定义是不完整的,过于简单,无法反映数据和数据间的关系,契约太过强硬,只要是所用到的行为子类都要遵守。于是我们很着急,这违反了OO初衷。哲学上告诉我们片面的抽象扩大化,会走到我们所期望的反面。可以说这就是一个例子,原本现实分类中很明显的继承关系,反而到了OO中,不成立了,或者说成为一个问题。不象现实中那样清晰。
我们为了简化而把事情搞复杂了。也许我们在纯粹的程序世界里面还可以不大在意这件事,按照自己定义的就可以了。但是我们要做需求分析时,这就成为大问题。那是必须和现实世界映射上的,任何的扭曲都会带来很多的麻烦。现在工作中我们的麻烦确实很多,原本清晰可见的关系,我们要重新调理。于是我们开始思考。
我们要用现实世界中的关系来指导OO设计,于是什么LSP,DBC都冒出来告诉我们怎么做。可是还是不行。
下一篇讨论这个问题在做用例分析时可能造成的泥潭。如何回避。
在我的blog:http://yingyiyy.blog.163.com/有后续文章。讲谈到这在工作中的实际意义。
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月01日 20:24
|
回复
|
|
我不知道谁讨论说正方形不是长方形的子类的 你能把文章给我转贴一下么?? 我觉得既然从数学定义上是,实际设计也一定是。 要不然OO的设计就是个错误
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月01日 21:53
|
回复
|
|
我觉得可能是这个问题,当 正方形继承长方形的时候,可以使正方形is a长方形 但是无法保证,x形继承正方形时,使x形既具有正方形的行为又具有长方形的行为
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月01日 22:11
|
回复
|
|
没有明白楼上的意思 x继承了正方形必然具备正方形的特性 所谓继承的意思就是 XX就是XX 男人就是人 ,女人是人 人生孩子是错的 必须是女人生孩子 楼主是说 老女人不具备生孩子的方法么,他具备这个方法,但是返回的东西不同?? 可是这在生活中也是必然的 if(age > 60) return null; 或者throw excption(“年纪太大”) 不是这样么??
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月01日 22:48
|
回复
|
|
其实,这在《java编程思想》里面认为是可以成立的。只不过某些涉及父类的方法要修改。 我认为也是成立的。只不过我们从这个争论为什么会发生,会发现类定义里面类太简单,没有涉及到约束的问题。 这是要说的重点。一个事物必然要包括一个约束问题。也就是说一个类要成功映射。不是他的所有属性,方法都必须被遵守,而是只要它符合一个约束,就成立了。
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月01日 23:30
|
回复
|
|
|
就好像椭圆和圆的关系一样。如果椭圆继承了圆,那么就会产生麻烦。一个圆引用指向一个椭圆的实例。那么给圆半径赋值这个操作到椭圆上面就麻烦了。圆的半径是一样的。椭圆则是不一样的,有一个长的,一个短的。该怎么办?
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月02日 09:20
|
回复
|
|
to siberian 怎么可能那?? 这是一个典型的约束啊 由于一个事务的状态改变而行为不同 这时候使用state模式啊 交给他的state模型来做 30岁的女人做什么 60岁的女人做什么 这些不是约束么??
to wlmouse 园是椭圆的子类 因为所有基于椭圆的数学运算都能运用在园上 我们说 园是一种特殊的椭圆 可是不能说椭圆是一种特殊的圆
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月02日 11:15
|
回复
|
|
我的意思是继承是is a的关系如果硬要用继承来描述长方形和正方形 那么实际的关系应该是is a而不是like a(正方形就是长方形吗?) 并且在考虑如果又有一个对象继承了正方形,或者继承了长方形,那他 又是什么,?现实世界不可能有这种情况,但是程序中无法保证,(除非 正方形是final)并且继承保证了当父类能用的地方子类也能用,而真要继承 是需要修改正方形内部逻辑,那么客户端调用的时候就无法保证了(难道父类和子类完全不同?) 我觉得描述正方形和长方形有3中解决方案 1,共同实现一个抽象的图形类或图形接口 2,考虑用组合,而不是继承 3,将正方形定义为final,并且保证其内部逻辑的和理性 且这三种方案的代码耦合度是逐步增加的
其实我个人一直反对用计算机完美的描述现实世界的逻辑,毕竟计算机是01的,太精确了 而现实世界不是这么回事,计算机应该是面向问题的,而不是面向逻辑(其实数学建模本 身也是面向问题的)
|
|
|
|
|
|
回复:re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月02日 13:19
|
回复
|
|
Coolyu0916 你明显你弄混了,类的内部问题和类与子类的关联问题.
你说30女,60女那是类的内部的.并没有表达到外面来. 而你建立了30女的类,60女的类的时候.那个约束就变成了类本身的重要的东西.
至于用状态模式也好,不用状态模式也好,不过是设计时的技巧,这些约束还是类定义本身至关重要的东西.不能随便的把它外在了.
|
|
|
|
|
|
回复:re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月02日 13:29
|
回复
|
|
你说的三种方法,其实在别处的讨论中已经提到.例如阎宏博士哪里就有一个大坑来讨论这问题. 而我今天说到这个问题是,是从类定义的缺乏约束的明确表达这个角度来的.毕竟清晰,无歧义的映射是OO得终极目标,任何一本讲述OO的书都会提到这一点。 我在blog将提到在实际工作中,这会造成那些问题。
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月02日 13:33
|
回复
|
|
siberian , state模式并不暴露state的 我们使用的统一的方法,给用户也是统一的接口 不过在不同的state下我们引用不同的state类
用户使用的时候肯定是 woman.setAge(30); woman.procreate(); 如果不给出age 就采用默认的age,这种接口不对么?? 我们平时说女人生孩子,一般来说我们都是认为是年轻的妇女 但是当你告诉他是一个小女孩或者老太太的时候,调用生孩子的方法必然是一个空或者是一个异常(你告诉别人她不能生孩子,或者你跟别人说这是开玩笑) 定义接口的时候你不需要关心这些问题,因为问题只有真的发生才有意义(说女人生孩子没有意义,必须说某个女人生孩子才有意义) 你在考虑问题的时候只要让其具备功能,当你认为某个方法可能存在疑义或者可能出现问题的时候,要在子类或者方法中进行控制。
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月02日 13:48
|
回复
|
|
checkcode 说实话,我一直到现在还不明白你说的意思
我们举例 如果一个对象 x 继承了正方形 比如说 (x为边大于5的正方形)我们称之为大正方吧
你要对图形计算面积,或者周长 那么你有什么不能定义那?? 利用长方形的方法就可以了
子类不使用父类的实现不可以么??
|
|
|
|
|
|
回复:re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月02日 14:10
|
回复
|
|
toCoolyu0916 咱们在说类之间的关系.这个时候还处在从需求得到分析类的时刻,而没有到后面设计时运用某种技巧,某种模式的时候. 这个时候,那些职责是他本身的.那些职责是外在的.和state还扯不上关系。 比如说,一个女人类他有哪些行为,那些约束。那么state模式只不过是在确定了这个分析类之后的优化处理,希望把女人类某些东西外包了。
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月02日 14:51
|
回复
|
|
那么我们就从需求方面走
首先我们确定了人的行为 我们不可能设计一个万能的persion class 我们只要实现有限的功能,在系统中用到的,比如eat() sleep() 现在要在性别上进行区分 这时候我们应当考虑需要怎样区分了,这个区分是为了标识还是为了实现 比如只是为了表示一个身份,一个证件,而不需要一些女人特定的动作,完全就不必需要子类,或者只是为了添加一些附加功能,也是不需要的。 这个必须从逻辑上说的通,你不能说 persion.procreate(),这个不符合逻辑,用你这个接口的人也会晕的,必须是woman.procreate(),这个时候你说不需要继承,使用组合么??或者是简单的引入一个方法么??
至于具体能不能procreate,需求的时候会告诉你,当女人在20-50的时候可能会生育,但是是20还是50是在运行中才会体现的,不是你设计接口时考虑的问题。那是到了详细设计的时候你才要关心的。
|
|
|
|
|
|
re:我来讨论一下纯理论的老问题.长方形和正方形的继承关系.
|
发表: 2007年03月02日 15:32
|
回复
|
|
类的约束,我们创建一个Person,那么作为一个顶级类,它可以没有约束,作为一个空泛的类而存在,因为它处在抽象的顶级。 但是我们一旦有了一个子类,并且子类的相对于父类有了约束,比如长方形中长和宽可以随便数值,但是到了正方形中不行了。他们要相等,不相等的就不是正方形。这个子类很明显是靠增加约束来建立的,而不是功能的扩展。 我们在需求中挖掘出子类之后,(注意不是为了方便而创造出来的,而是现实中有了子类),就要确定它是否有了约束,还是只是扩展了。 在你举的例子中,如果生育期妇女这个概念常常出现,那么它就应该是一个类,它成立的约束条件就是年龄在20-50,性别女。不满足这个约束,这个类就不成立。它并不是一个运行时的问题,而是一个类本身的,与生俱来的东西。你可以再后来的设计中,把它放到配置文件中,但是不能回避的是,它是类本身的东西。不符合这个约束,他就不是这个类。 接口设计还要排在分析类获取的后面。至于是否方便也不是考虑的问题。我们在这个阶段是要做到完美的映射。
|
|
|
|
|
|
这个主题有 36 回复 / 3 页 [
1 2 3
下一页
]
|
|
|