问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

为什么在Java编程中的继承多数是有害的

发布网友 发布时间:2022-04-15 08:01

我来回答

2个回答

懂视网 时间:2022-04-15 12:22

  

  大多数好的设计者象躲避瘟疫一样来避免使用实现继承(extends 关系)。实际上80%的代码应该完全用interfaces写,而不是通过extends。“Java设计模式”一书详细阐述了怎样用接口继承代替实现继承。这篇文章描述设计者为什么会这么作。

  Extends是有害的;也许对于Charles Manson这个级别的不是,但是足够糟糕的它应该在任何可能的时候被避开。“JAVA设计模式”一书花了很大的部分讨论用interface继承代替实现继承。

  好的设计者在他的代码中,大部分用interface,而不是具体的基类。本文讨论为什么设计者会这样选择,并且也介绍一些基于interface的编程基础。

  接口(Interface)和类(Class)?

  一次,我参加一个Java用户组的会议。在会议中,Jams Gosling(Java之父)做发起人讲话。在那令人难忘的Q&A部分中,有人问他:“如果你重新构造Java,你想改变什么?”。“我想抛弃classes”他回答。在笑声平息后,它解释说,真正的问题不是由于class本身,而是实现继承(extends) 关系。接口继承(implements关系)是更好的。你应该尽可能的避免实现继承。

  失去了灵活性

  为什么你应该避免实现继承呢?第一个问题是明确的使用具体类名将你固定到特定的实现,给底层的改变增加了不必要的困难。

  在当前的敏捷编程方法中,核心是并行的设计和开发的概念。在你详细设计程序前,你开始编程。这个技术不同于传统方法的形式----传统的方式是设计应该在编码开始前完成----但是许多成功的项目已经证明你能够更快速的开发高质量代码,相对于传统的按部就班的方法。但是在并行开发的核心是主张灵活性。你不得不以某一种方式写你的代码以至于最新发现的需求能够尽可能没有痛苦的合并到已有的代码中。

  胜于实现你也许需要的特征,你只需实现你明确需要的特征,而且适度的对变化的包容。如果你没有这种灵活,并行的开发,那简直不可能。

  对于Inteface的编程是灵活结构的核心。为了说明为什么,让我们看一下当使用它们的时候,会发生什么。考虑下面的代码:

  f()
  {
  LinkedList list = new LinkedList();
  //...
  g( list );
  }

  g( LinkedList list )
  {
  list.add( ... );
  g2( list )
  }

  假设一个对于快速查询的需求被提出,以至于这个LinkedList不能够解决。你需要用HashSet来代替它。在已有代码中,变化不能够局部化,因为你不仅仅需要修改f()也需要修改g()(它带有LinkedList参数),并且还有g()把列表传递给的任何代码。象下面这样重写代码:

  f()
  {
  Collection list = new LinkedList();
  //...
  g( list );
  }

  g( Collection list )
  {
  list.add( ... );
  g2( list )
  }

  这样修改Linked list成hash,可能只是简单的用new HashSet()代替new LinkedList()。就这样。没有其他的需要修改的地方。

  作为另一个例子,比较下面两段代码:

  f()
  {
  Collection c = new HashSet();
  //...
  g( c );
  }

  g( Collection c )
  {
  for( Iterator i = c.iterator(); i.hasNext() )
  do_something_with( i.next() );
  }

  和

  f2()
  {
  Collection c = new HashSet();
  //...
  g2( c.iterator() );
  }

  g2( Iterator i )
  {
  while( i.hasNext() )
  do_something_with( i.next() );
  }


  g2()方法现在能够遍历Collection的派生,就像你能够从Map中得到的键值对。事实上,你能够写iterator,它产生数据,代替遍历一个Collection。你能够写iterator,它从测试的框架或者文件中得到信息。这会有巨大的灵活性。

  耦合

  对于实现继承,一个更加关键的问题是耦合---令人烦躁的依赖,就是那种程序的一部分对于另一部分的依赖。全局变量提供经典的例子,证明为什么强耦合会引起麻烦。例如,如果你改变全局变量的类型,那么所有用到这个变量的函数也许都被影响,所以所有这些代码都要被检查,变更和重新测试。而且,所有用到这个变量的函数通过这个变量相互耦合。也就是,如果一个变量值在难以使用的时候被改变,一个函数也许就不正确的影响了另一个函数的行为。这个问题显著的隐藏于多线程的程序。

  作为一个设计者,你应该努力最小化耦合关系。你不能一并消除耦合,因为从一个类的对象到另一个类的对象的方法调用是一个松耦合的形式。你不可能有一个程序,它没有任何的耦合。然而,你能够通过遵守OO规则,最小化一定的耦合(最重要的是,一个对象的实现应该完全隐藏于使用他的对象)。例如,一个对象的实例变量(不是常量的成员域),应该总是private。我意思是某段时期的,无例外的,不断的。(你能够偶尔有效地使用protected方法,但是protected实例变量是可憎的事)同样的原因你应该不用get/set函数---他们对于是一个域公用只是使人感到过于复杂的方式(尽管返回修饰的对象而不是基本类型值的访问函数是在某些情况下是由原因的,那种情况下,返回的对象类是一个在设计时的关键抽象)。

  这里,我不是书生气。在我自己的工作中,我发现一个直接的相互关系在我OO方法的严格之间,快速代码开发和容易的代码实现。无论什么时候我违反中心的OO原则,如实现隐藏,我结果重写那个代码(一般因为代码是不可调试的)。我没有时间重写代码,所以我遵循那些规则。我关心的完全实用?我对干净的原因没有兴趣。

热心网友 时间:2022-04-15 09:30

多继承使得类的继承关系变得复杂,违反了单一职责原则,在复杂工程中容易导致工程不可控。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
不干胶印刷设备多少钱一套 小型不干胶印刷机价格 什么是走水运 水路的特点是什么 疯狂僵尸机游戏怎么玩,植物大战僵尸高清版怎么玩 植物大战僵尸2 植物大战僵尸2戴夫最好的朋友是谁? 怎么下载疯狂的戴夫游戏 游戏下载地址 小红书数据分析工具推荐 三分钟做好一张小红书封面,不同平台超好用的高效率工具你造吗_百度知... 网球王子的剧场版都有哪些啊 网球王子剧场版:英国式庭球城决战DVD情报 在梯形上底上做高正确吗 怎么煲牛肉当归汤,有什么功效? 牛肉当归汤喝了有什么好处 当归牛肉汤有什么功效 当归牛肉汤的说明 过直线外一点和这条直线平行的平面有几个 鲜当归可以煮牛肉吗 过直线外一点和该直线平行的平面有几个? 过在一条直线的3个点,可以做无数个平面,为什么呢 过两条平行的直线,可以做一个平面,为什么呢 喝当归牛肉汤有什么好处 ? 怎样理解“判断题:一点和一条直线确定一个平面(不正确)如果点在直线上,可以有无穷多个平面”这句话 牛肉可以蒸当归吗 “在同一条直线上的三个点可以确定无数个平面”是什么意思? 嵊泗列岛看日出两日游怎么去? 经过一条直线并与一个点距离为5的平面有无数多个 两平面相交有一条公共线正确吗? 为什么经过一点,两点,或在一条直线上的三点可有无数个平面 过一条直线与一个平面垂直的平面个数为多少 “一条直线确定无数个平面”这种说法对吗? 能说过一条直线可确定无数个平面吗 从一个等腰梯形的上底端点画高,把下底分为1:3两端。下底长8厘米,并且高等于底的4分之1.求面积 U盘插进电脑那里,下面那里有显示...可就是不能下载歌曲...我应该怎么搞才好? 梯形上底可以画高吗 新能源车补贴政策? 不知道为什么我的手机内存卡用U盘插进电脑,打不开,还弹出一个窗口,还不能下歌了 用朋友的营业执照,食品流通许可证,怎样在淘宝开店。 在梯形的上底和下底之间可以画多少条高,这些高的长度是多少 电脑有显示移动U盘,怎么下不了歌 为什么我的u盘插在电脑上能显示出来 却不能下载歌? QQ音乐上提示已经下好了 在u盘上找不到啊 昨天还能 电脑插u盘下歌卡住了,是不是u盘原因 车里插的u盘突然不能放歌了,插在电脑上也没反应是怎么回事啊? 电脑哪个程序坏了用u盘下不了歌 构图中如何正确安排主体、陪体、前景、背景、空白? 怎么用u盘在电脑上下歌..连接不了... 关于拍摄技巧!拍摄玉器金属、表面反光的东西有什么技巧?关于光线、背景等,怎样拍出来的照片效果好! 请描述一下照片的构图,并对背景的处理方式和方法,以及背景对主体或主题有什么样的 前景与背景在框架式构图中起到什么作用? 天猫买东西,有一张奖状“卓越买家奖”说加微信可领红包,定期有商品 重装系统后鼠标光标一直一闪一闪的,怎么回事?而且我的是XP系统 为什么鼠标光标在桌面会不停闪?xp系统的...为什么?