1.熟悉C++的程序员对构造函数肯定不陌生,为什么要有构造函数呢??
变量的初始化和消除一直是编写安全的程序代码两个重要的方面,许多C程序的错误都是由于程序员忘记初始化一个变量造成的。C++的发明者总结了这个问题,于是提出了构造函数和析构函数的概念,强迫程序员去初始化变量和显式的销毁对象,Bjarne Stroustrup (C++发明者)牛的一塌糊涂,服了他!!
2.谈谈Java中的构造函数
其实Java中的构造函数采用了C++的模式(随让Bjarne Stroustrup做的那么好呢,大家都用了)
有如下特点:
(1).构造函数一定要与类名相同,这样可以保证在构造一个对象的时候,编译器会自动调用它的构造函数;
(2).构造函数没有返回值,构造函数不是一般的函数,自然要区别与一般的了;
(3).构造函数可以重载,至于什么是函数的重载,简单提一下,具体可以看我以后对C++的介绍,
函数的重载就是函数相同的函数名(在C语言中决不可以有相同的函数名),不同的函数参数;
编译器区别重载函数的依据是什么呢?主要是通过参数的类型,个数和顺序,(注意函数的返回值不作为依据的);
函数的重载其实也是减少代码重复的一个方面,比如打这个字可以有很多对象,打人,打男人,打女人等(其实打的动作是一样的,只是对象不一样),在C语言中你要写这么多的函数来描述这几个行为,但是在支持函数重载的语言中,你只要写一个函数就够了,打的对象作为参数传进去就行了,
(至于函数重载引起的其它问题比如重载的是基本类型会涉及到类型转换的问题,这些以后再说,我们要抓住主要矛盾嘛)
3.默认构造函数
class Value{
int i;
}
public class DefaultConstructor {
public static void main(String[] args) {
Value v = new Value(); // 此行调用默认构造函数
}
}
int i;
}
public class DefaultConstructor {
public static void main(String[] args) {
Value v = new Value(); // 此行调用默认构造函数
}
}
上面的程序中由于Value没有提供构造函数,编译器会帮我们生成一个默认的构造函数,
class Value{
Value(int data)
{
i=data;
}
int i;
}
public class DefaultConstructor {
public static void main(String[] args) {
Value v = new Value(); // 此行出错
int i;
}
public class DefaultConstructor {
public static void main(String[] args) {
Value v = new Value(); // 此行出错
}
}
}
上面的程序中由于Value已经提供了构造函数,所以编译器不会帮你生成默认构造函数的;
可能C++老鸟觉得没什么吧,和C++一样嘛,在此说一下,C++中并不是这么简单的,具体可以看<Inside The C++ Object Model>中有相关的说明
4.this关键字
类中的函数是共享给对象的,也就是说对象调用的方法是类中的方法,那么类是如何知道是哪个对象调用我的方法呢,是通过关键字this,this 是什么,this是当前对象的句柄
class Value{
int i;
int i;
int getValue()
{
return i;
}
}
public class DefaultConstructor {
public static void main(String[] args) {
Value v1 = new Value(),v2=new Value();
}
public class DefaultConstructor {
public static void main(String[] args) {
Value v1 = new Value(),v2=new Value();
v1.getValue();
v2.getValue(); //Value是如何知道是v1调用还是v2调用的呢,是通过this引用解决这个问题的
}
}
}
我们可以通过this引用在方法内部获得当前对象的句柄,从而来操纵对象的其它东东
注意:如果我们使用了static 关键字,那么this关键字就失效了
5.构造函数中调用构造函数
若为一个类写了多个构造函数,那么经常都需要在一个构造函数里调用另一个构造函数,以避免写重复的代码。可用this关键字做到这一点。
通常,当我们说this的时候,都是指“这个对象”或者“当前对象”。而且它本身会产生当前对象的一个句柄。在一个构造函数中,若为其赋予一个自变量列表,那么this关键字会具有不同的含义:它会对与那个自变量列表相符的构造函数进行明确的调用(通过参数来识别调用哪个构造函数)。这样一来,我们就可通过一条直接的途径来调用其他构造函数了
通常,当我们说this的时候,都是指“这个对象”或者“当前对象”。而且它本身会产生当前对象的一个句柄。在一个构造函数中,若为其赋予一个自变量列表,那么this关键字会具有不同的含义:它会对与那个自变量列表相符的构造函数进行明确的调用(通过参数来识别调用哪个构造函数)。这样一来,我们就可通过一条直接的途径来调用其他构造函数了
注:我们不可以在非构造函数中调用构造函数
6.Java可以在类中初始化变量(在C++中是不允许的,虽然很多C++新手每次都想这么做)
class Value{
int i=100;
int i=100;
int getValue()
{
return i;
}
}
}
7.static 变量的初始化
若数据是静态的(static),那么同样的事情就会发生;如果它属于一个基本类型(主类型),而且未对其初始化,就会自动获得自己的标准基本类型初始值;如果它是指向一个对象的句柄,那么除非新建一个对象,并将句柄同它连接起来,否则就会得到一个空值(NULL)。
如果想在定义的同时进行初始化,采取的方法与非静态值表面看起来是相同的。但由于static值只有一个存储区域,所以无论创建多少个对象,都必然会遇到何时对那个存储区域进行初始化的问题
如果想在定义的同时进行初始化,采取的方法与非静态值表面看起来是相同的。但由于static值只有一个存储区域,所以无论创建多少个对象,都必然会遇到何时对那个存储区域进行初始化的问题
8.明确的静态
明确进行的静态初始化
Java允许我们将其他static初始化工作划分到类内一个特殊的“static构建从句”(有时也叫作“静态块”)里。它看起来象下面这个样子:
尽管看起来象个方法,但它实际只是一个static关键字,后面跟随一个方法主体。与其他static初始化一样,这段代码仅执行一次——首次生成那个类的一个对象时,或者首次访问属于那个类的一个static成员时(即便从未生成过那个类的对象)
Java允许我们将其他static初始化工作划分到类内一个特殊的“static构建从句”(有时也叫作“静态块”)里。它看起来象下面这个样子:
class Spoon { static int i; static { i = 47; } // . . .
尽管看起来象个方法,但它实际只是一个static关键字,后面跟随一个方法主体。与其他static初始化一样,这段代码仅执行一次——首次生成那个类的一个对象时,或者首次访问属于那个类的一个static成员时(即便从未生成过那个类的对象)