Java和C++在细节上的差异(一) (五)

2014-11-24 03:03:11 · 作者: · 浏览: 5
BaseClass with i.
35 This is SonClass with i */
  在Java的域变量初始化方法中存在初始化块的方式,既除声明即初始化、构造函数初始化之外的第三种域变量初始化方式。在一个类的声明中可以存在多个代码块,只要构造类的对象,这些块就会被执行,然后再运行类的构造函数。静态域变量可以在静态初始化块中完成初始化的工作,但是该初始化块只是在类第一次加载时被执行一次,之后都将不再被执行。见如下代码:
1 class Employee {
2 public Employee(String n,double s) {
3 name = n;
4 salary = s;
5 }
6
7 ...
8
9 private static int nextId;
10 private int id;
11 private String name;
12 private double salary;
13
14 //object initialization block.
15 {
16 id = nextId;
17 nextId++;
18 }
19
20 //static initialization block.
21 static
22 {
23 Random generator = new Random();
24 nextId = generator.nextInt();
25 }
26 }
6. C++的对象析构和Java对象的finalize方法:
C++是有显式的析构方法,其中放置一些当对象不再使用时需要执行的清理代码。在析构函数中,最常见的操作时回收分配给对象的存储空间,系统资源等。有Java有自动的垃圾回收器,不需要人工回收内存,所以Java并不支持析构函数。如果打算在Java的代码中完成类似的工作,可以通过为该类添加finalize方法,该方法将会在垃圾收集器清除对象之前调用,在实际应用中,不要依赖于使用finalize方法回收任何短缺的资源,这是因为很难知道这个方法什么时候才能调用。如果某个资源确实需要在使用完毕后立刻关闭,那么就需要由人工来管理。可以应用一个类似dispose或close的方法完成相应的清理操作。特别需要说明,如果一个类使用了这样的方法,当对象不再被使用时一定要调用它。
7. Java的包 vs C++的名字空间
他们具有极为相同的只能,即防止名字污染。当一个应用程序中存在多个第三方组件,那么不同组件中命名了相同名称的类将是极为可能发生的,如Java中的Date类,在java.util和java.sql中均存在该名称的类的声明。为了有效的防止名字污染,C++中采用了namespace和using namespace的指令来明确定义某个类具体所位于的具体位置,Java中则采用了package和import语句。
Java在Java SE5.0 开始,import语句不仅可以导入类,还增加了导入静态方法和静态域的功能。如import static java.lang.System.*。在完成该静态导入之后,就可以在剩下的代码中直接使用System类的静态方法和静态域了,如out.println();exit(0)。该技巧主要用于带有较长名称的常量,如if (d.get(DAY_OF_WEEK) == MONDAY) ...,看起来比if (d.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) ...要容易的多。

三、继承:

  1. Java和C++在对象继承方面的主要差异:
  对象的继承性是所有面向对象语言都支持的面向对象特性之一,Java和C++作为两个重要的面向对象开发语言在此方面有着较多的相似性,但是在有些概念的表示方式上还是存在着一定的差异,先列举如下:
  1) 对象继承的关键字,Java中采用extents关键字,如class DeriveClass extends BaseClass, 在C++中则使用(:)冒号表示类之间的继承,如class DeriveClass : public BaseClass。
  2) Java的继承方式中不存在public,protected和private,其表现行为和C++中的public继承完全一致。
  3) 在有些情况下,子类中的方法需要显式的调用超类中的方法实现,特别是当子类中也存在同样方法签名的实现时,如果没有明确的指出需要调用超类的方法,Java的编译器会将子类当前的方法列为本次调用的候选方法,见如下代码:
1 class DeriveClass extends BaseClass {
2 public double getSalary() {
3 double baseSalary = getSalary();
4 return baseSalary + bonus;
5 }
6 }
  以上代码中的getSalary()方法将会递归的调用其自身,而开发者的实际用意是调用超类中的getSalary方法,由于超类和子类中具有相同签名的该方法,因此编译器在此时选择了子类中的getSalary。其修改方式如下:
1 class DeriveClass extends BaseClass {
2 public double getSalary() {
3 double baseSalary = super.getSalary();
4 return baseSalary + bonus;
5 }
6 }
  加上关键字super明确的指出要调用超类中的getSalary方法。在C++中的实现方式为BaseClass::getSalary(),既在方法签名的前面加上父类的名字和两个连在一起的冒号(::)。
1 class DeriveClass : public BaseClass {
2 public:
3 double getSalary() {
4 double baseSalary = BaseClass::getSalary();
5 return baseSalary + bonus;
6 }
7 }
  4) Java中所有未声明为final的方法都视为可以继承的虚方法。在C++中,尽管没有此类限制,但是在实际的应用中还是存在一些潜在的技巧以达到此效果。对于C++类中声明的公有成员方法,如果该方法未声明为virtual,既虚函数,则暗示该类的子类实现者不要在子类中覆盖(override)该方法。
  5) Java中不支持多重继承,不仅有效的避免了C++因多重继承而带来的一些负面影响,与此同时,在Java中可以通过继承(