文档

Java™教程
隐藏目录
创建对象
路径:学习Java语言
课程:类和对象
章节:对象

创建对象

如你所知,一个类提供了对象的蓝图;你可以从一个类创建一个对象。以下代码取自CreateObjectDemo程序,每个语句都创建一个对象并将其赋值给一个变量:

Point originOne = new Point(23, 94);
Rectangle rectOne = new Rectangle(originOne, 100, 200);
Rectangle rectTwo = new Rectangle(50, 100);

第一行创建了一个Point类的对象,而第二行和第三行分别创建了一个Rectangle类的对象。

这些语句中的每个部分都有三个部分(下面会详细讨论):

  1. 声明:加粗的代码是变量声明,将变量名与对象类型关联起来。
  2. 实例化new关键字是Java中创建对象的操作符。
  3. 初始化new操作符后面跟着对构造方法的调用,用于初始化新对象。

声明一个变量以引用一个对象

之前,你学到的是声明一个变量的方式:

类型 名称;

这样通知编译器,你将使用名称引用类型为类型的数据。对于基本类型的变量,这个声明还会为变量保留适当大小的内存空间。

你也可以在单独的一行上声明一个引用变量。例如:

Point originOne;

如果你这样声明originOne,它的值将在实际创建并赋值给它之前是未确定的。仅仅声明一个引用变量并不会创建一个对象。为此,你需要使用new操作符,如下一节所述。在使用变量之前,你必须将一个对象赋值给originOne。否则,将会得到编译器错误。

处于这种状态的变量,当前没有引用任何对象,可以如下图所示表示(变量名originOne加上一个指向空的引用):

originOne is null.

实例化一个类

new操作符通过为新对象分配内存并返回对该内存的引用来实例化一个类。 new操作符还会调用对象的构造函数。


注意: "实例化一个类"和"创建一个对象"是指同一件事情。当你创建一个对象时,你正在创建一个类的"实例",因此是在"实例化"一个类。

new操作符需要一个后缀参数:对构造函数的调用。构造函数的名称提供了要实例化的类的名称。

new操作符返回对它创建的对象的引用。这个引用通常被赋值给一个合适类型的变量,如:

Point originOne = new Point(23, 94);

new操作符返回的引用不必被赋值给一个变量。它也可以直接在表达式中使用。例如:

int height = new Rectangle().height;

下一节将讨论这个语句。

初始化对象

这是Point类的代码:

public class Point {
    public int x = 0;
    public int y = 0;
    //构造函数
    public Point(int a, int b) {
        x = a;
        y = b;
    }
}

这个类包含一个构造函数。你可以通过它的声明来识别构造函数,它使用与类相同的名称,并且没有返回类型。在Point类中的构造函数接受两个整数参数,如代码(int a, int b)所声明的那样。下面的语句为这些参数提供了23和94作为值:

Point originOne = new Point(23, 94);

执行这个语句的结果可以在下图中说明:

originOne现在指向一个Point对象。

这是Rectangle类的代码,其中包含四个构造函数:

public class Rectangle {
    public int width = 0;
    public int height = 0;
    public Point origin;

    // 四个构造函数
    public Rectangle() {
        origin = new Point(0, 0);
    }
    public Rectangle(Point p) {
        origin = p;
    }
    public Rectangle(int w, int h) {
        origin = new Point(0, 0);
        width = w;
        height = h;
    }
    public Rectangle(Point p, int w, int h) {
        origin = p;
        width = w;
        height = h;
    }

    // 一个用于移动矩形的方法
    public void move(int x, int y) {
        origin.x = x;
        origin.y = y;
    }

    // 一个计算矩形面积的方法
    public int getArea() {
        return width * height;
    }
}

每个构造函数都可以使用基本类型和引用类型提供矩形的原点、宽度和高度的初始值。如果一个类有多个构造函数,它们必须具有不同的签名。Java编译器根据参数的数量和类型来区分构造函数。当Java编译器遇到以下代码时,它知道调用需要一个Point参数和两个整数参数的Rectangle类的构造函数:

 
Rectangle rectOne = new Rectangle(originOne, 100, 200);

这调用了一个Rectangle类的构造函数,将origin初始化为originOne。此外,构造函数将width设置为100,height设置为200。现在有两个引用指向同一个Point对象-一个对象可以有多个引用,如下图所示:

现在矩形的原点变量也指向该点。

下面的代码调用了需要两个整数参数的Rectangle构造函数,这些参数提供了width和height的初始值。如果你检查构造函数内的代码,你会发现它创建了一个新的Point对象,其x和y值被初始化为0:

Rectangle rectTwo = new Rectangle(50, 100);

下面的语句中使用的Rectangle构造函数不接受任何参数,因此被称为无参构造函数:

Rectangle rect = new Rectangle();

所有的类至少有一个构造函数。如果一个类没有显式声明任何构造函数,Java编译器会自动提供一个无参构造函数,称为默认构造函数。这个默认构造函数调用了类父类的无参构造函数,或者如果类没有其他父类的话,调用了Object类的构造函数。如果父类没有构造函数(Object类有一个构造函数),编译器会拒绝该程序。


上一页:对象
下一页:使用对象