会计考友 发表于 2012-8-4 12:28:23

JAVU技巧:java中extends的危害(2)

 有一天,有人也许运行这个代码而且注重到Stack没有运行的如想象的那么快,而且能够在重负荷下使用。你能够重写Stack,以至于它不用ArrayList而且继续提高Stack的效率。这是新的倾向的和有意义的版本:
  [/代码]
  class Stack
  {
  private int stack_pointer = -1;
  private Object[] stack = new Object; public void push( Object article )
  {
  assert stack_pointer < stack.length;
  stack[ ++stack_pointer ] = article;
  }public Object pop()
  {
  assert stack_pointer >= 0;
  return stack[ stack_pointer-- ];
  } public void push_many( Object[] articles )
  {
  assert ( stack_pointer + articles.length ) < stack.length; System.arraycopy( articles, 0, stack, stack_pointer + 1, articles.length );
  Stack_pointer += articles.length;
  }
  }
  [/代码]注重到push_many不再多次挪用push()—它做块传输。新的Stack运行正常;事实上,比前一个版本更好。不幸的是,派生类Monitorable_stack不再运行,因为如不美观push_many()被挪用,它不正确的跟踪仓库的使用(push()的派生类版本不再经由过程担任的push_many()体例挪用,所以push_many()不再更新high_water_mark)。Stack是一个懦弱的类。与封锁它一样,事实上不成能经由过程小心来覆灭这些类型的错误。注重如不美观你用接口担任,你就没有这个问题,因为你没有担任对你有害的函数。如不美观Stack是接口,由Simple_stack和Monitorable_stack实现,那么代码就是加倍健壮的。我供给了一个基于接口的体例在Listing 0.1。这个解决体例和担任实现的体例一样的矫捷:你能够用Stack抽象术语来写代码而不必担忧你事实上在操作那种具体的仓库。因为两个实现必需供给公共接口的所有工具,它很难使工作变糟。我仍然有和写基类的代码一样的只写一次,因为我用封装而不是担任。在底层,我不得不经由过程封装类中的琐碎的访谒器体例来访谒缺省的实现。(例如,Monitorable_Stack.push(…)(在41行)不得不挪用在Simple_stack等价的体例).轨范员埋怨写所有这些行,可是写这出格行代码同消弭主要的潜在bug长短常小的成本。[/代码]
  Listing 0.1. 用接口消弭懦弱基类 1
页: [1]
查看完整版本: JAVU技巧:java中extends的危害(2)