编写高质量代码:改善Java程序的151个建议(10)

发表于:2012-3-19 09:25

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:秦小波    来源:51Testing软件测试网采编

  第3章 类、对象及方法

  书读得多而不思考,你会觉得自己知道的很多。

  书读得多而思考,你会觉得自己不懂的越来越多。

                    —伏尔泰

  在面向对象编程(Object-OrientedProgramming,OOP)的世界里,类和对象是真实世界的描述工具,方法是行为和动作的展示形式,封装、继承、多态则是其多姿多彩的主要实现方式,如此,OOP才会像现在这样繁荣昌盛、欣欣向荣。

  本章主要讲述关于Java类、对象、方法的种种规则、限制及建议,让读者在面向对象编程的世界中走得更远,飞得更高。

  建议31:在接口中不要存在实现代码

  看到这样的标题读者可能会纳闷:接口中有实现代码?这怎么可能呢?确实,接口中可以声明常量,声明抽象方法,也可以继承父接口,但就是不能有具体实现,因为接口是一种契约(Contract),是一种框架性协议,这表明它的实现类都是同一种类型,或者是具备相似特征的一个集合体。对于一般程序,接口确实没有任何实现,但是在那些特殊的程序中就例外了,阅读如下代码:

  1. public class Client {  
  2.      public static void main(String[] args) {  
  3.           //调用接口的实现  
  4.           B.s.doSomething();  
  5.      }  
  6. }  
  7. //在接口中存在实现代码  
  8. interface B{  
  9.      public static final S s = new S(){  
  10.           public void doSomething(){  
  11.             System.out.println("我在接口中实现了");  
  12.         }  
  13.      };  
  14. }  
  15. //被实现的接口  
  16. interface S{  
  17.      public void doSomething();  
  18. }

  仔细看main方法,注意那个B接口。它调用了接口常量,在没有任何显式实现类的情况下,它竟然打印出了结果,那B接口中的s常量(接口是S)是在什么地方被实现的呢?答案是在B接口中。

  在B接口中声明了一个静态常量s,其值是一个匿名内部类(Anonymous Inner Class)的实例对象,就是该匿名内部类(当然,可以不用匿名,直接在接口中实现内部类也是允许的)实现了S接口。你看,在接口中存在着实现代码吧!

  这确实很好,很强大,但是在一般的项目中,此类代码是严禁出现的,原因很简单:这是一种不好的编码习惯,接口是用来干什么的?接口是一个契约,不仅仅约束着实现者,同时也是一个保证,保证提供的服务(常量、方法)是稳定、可靠的,如果把实现代码写到接口中,那接口就绑定了可能变化的因素,这就会导致实现不再稳定和可靠,是随时都可能被抛弃、被更改、被重构的。所以,接口中虽然可以有实现,但应避免使用。

  注意:接口中不能存在实现代码。

  建议32:静态变量一定要先声明后赋值

  这标题看着让人很纳闷,什么叫做变量一定要先声明后赋值?Java中的变量不都是先声明后使用的吗?难道还能先使用后声明?能不能暂且不说,我们先来看一个例子,代码如下:

  1. public class Client {  
  2.      public static  int i=1;  
  3.      static{  
  4.          i=100;  
  5.      }  
  6.      public static void main(String[] args) {  
  7.           System.out.println(i);  
  8.     }  
  9. }

  这段程序很简单,输出100嘛!对,确实是100,我们再稍稍修改一下,代码如下:

  1. public class Client {  
  2.      static{  
  3.          i=100;  
  4.      }  
  5.      public static  int i=1;  
  6.      public static void main(String[] args) {  
  7.           System.out.println(i);  
  8.      }  
  9. }

  注意,变量i的声明和赋值调换了位置,现在的问题是:这段程序能否编译?如果可以编译那输出是多少?还要注意:这个变量i可是先使用(也就是赋值)后声明的。

  答案是:可以编译,没有任何问题,输出是1。对,你没有看错,输出确实是1,而不是100。仅仅调换了一下位置,输出就变了,而且变量i还真是先使用后声明的,难道这世界真的颠倒了?

41/41234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号