Documentation

The Java™ Tutorials
Hide TOC
Creating Objects创建对象
Trail: Learning the Java Language
Lesson: Classes and Objects
Section: Objects

Creating Objects创建对象

As you know, a class provides the blueprint for objects; you create an object from a class.如您所知,类为对象提供蓝图;从类创建对象。Each of the following statements taken from the CreateObjectDemo program creates an object and assigns it to a variable:CreateObjectDemo程序中获取的以下每条语句都会创建一个对象并将其分配给一个变量:

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

The first line creates an object of the Point class, and the second and third lines each create an object of the Rectangle class.第一行创建Point类的对象,第二行和第三行分别创建Rectangle类的对象。

Each of these statements has three parts (discussed in detail below):这些陈述中的每一个都有三个部分(详细讨论如下):

  1. Declaration宣言: The code set in bold are all variable declarations that associate a variable name with an object type.粗体代码集是将变量名称与对象类型关联的所有变量声明。
  2. Instantiation实例化: The new keyword is a Java operator that creates the object.new关键字是创建对象的Java运算符。
  3. Initialization初始化: The new operator is followed by a call to a constructor, which initializes the new object.new运算符后面是对构造函数的调用,构造函数初始化新对象。

Declaring a Variable to Refer to an Object声明引用对象的变量

Previously, you learned that to declare a variable, you write:之前,您了解到,要声明变量,您需要编写:

type name;

This notifies the compiler that you will use name to refer to data whose type is type.这会通知编译器,您将使用name来引用类型为type的数据。With a primitive variable, this declaration also reserves the proper amount of memory for the variable.对于基元变量,此声明还为变量保留适当的内存量。

You can also declare a reference variable on its own line.您还可以在引用变量本身的行上声明引用变量。For example:例如:

Point originOne;

If you declare originOne like this, its value will be undetermined until an object is actually created and assigned to it.如果像这样声明originOne,则在实际创建并为其指定对象之前,其值将不确定。Simply declaring a reference variable does not create an object.仅声明引用变量不会创建对象。For that, you need to use the new operator, as described in the next section.为此,需要使用new操作符,如下一节所述。You must assign an object to originOne before you use it in your code.在代码中使用originOne之前,必须将对象指定给它。Otherwise, you will get a compiler error.否则,将出现编译器错误。

A variable in this state, which currently references no object, can be illustrated as follows (the variable name, originOne, plus a reference pointing to nothing):处于这种状态的变量(当前未引用任何对象)可以如下所示(变量名originOne加上一个不指向任何对象的引用):

originOne is null.

Instantiating a Class实例化类

The new operator instantiates a class by allocating memory for a new object and returning a reference to that memory.new操作符通过为新对象分配内存并返回对该内存的引用来实例化类。The new operator also invokes the object constructor.new操作符还调用对象构造函数。


Note: The phrase "instantiating a class" means the same thing as "creating an object."短语“实例化类”的意思与“创建对象”的意思相同When you create an object, you are creating an "instance" of a class, therefore "instantiating" a class.当您创建一个对象时,您正在创建一个类的“实例”,从而“实例化”一个类。

The new operator requires a single, postfix argument: a call to a constructor.new运算符需要一个后缀参数:调用构造函数。The name of the constructor provides the name of the class to instantiate.构造函数的名称提供要实例化的类的名称。

The new operator returns a reference to the object it created.new操作符返回对其创建的对象的引用。This reference is usually assigned to a variable of the appropriate type, like:此引用通常分配给适当类型的变量,如:

Point originOne = new Point(23, 94);

The reference returned by the new operator does not have to be assigned to a variable.new运算符返回的引用不必指定给变量。It can also be used directly in an expression.它也可以直接用于表达式中。For example:例如:

int height = new Rectangle().height;

This statement will be discussed in the next section.此声明将在下一节中讨论。

Initializing an Object初始化对象

Here's the code for the Point class:以下是Point类的代码:

public class Point {
    public int x = 0;
    public int y = 0;
    //constructor
    public Point(int a, int b) {
        x = a;
        y = b;
    }
}

This class contains a single constructor.这个类包含一个构造函数。You can recognize a constructor because its declaration uses the same name as the class and it has no return type.您可以识别构造函数,因为它的声明使用与类相同的名称,并且没有返回类型。The constructor in the Point class takes two integer arguments, as declared by the code (int a, int b).Point类中的构造函数采用代码(int a, int b)声明的两个整数参数。The following statement provides 23 and 94 as values for those arguments:以下语句提供23和94作为这些参数的值:

Point originOne = new Point(23, 94);

The result of executing this statement can be illustrated in the next figure:执行此语句的结果如下图所示:

originOne now points to a Point object.

Here's the code for the Rectangle class, which contains four constructors:下面是Rectangle类的代码,该类包含四个构造函数:

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

    // four constructors
    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;
    }

    // a method for moving the rectangle
    public void move(int x, int y) {
        origin.x = x;
        origin.y = y;
    }

    // a method for computing the area of the rectangle
    public int getArea() {
        return width * height;
    }
}

Each constructor lets you provide initial values for the rectangle's origin, width, and height, using both primitive and reference types.每个构造函数都允许您使用基本类型和引用类型为矩形的原点、宽度和高度提供初始值。If a class has multiple constructors, they must have different signatures.如果一个类有多个构造函数,那么它们必须具有不同的签名。The Java compiler differentiates the constructors based on the number and the type of the arguments.Java编译器根据参数的数量和类型区分构造函数。When the Java compiler encounters the following code, it knows to call the constructor in the Rectangle class that requires a Point argument followed by two integer arguments:当Java编译器遇到以下代码时,它知道在Rectangle类中调用构造函数,该类需要一个Point参数,后跟两个整数参数:

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

This calls one of Rectangle's constructors that initializes origin to originOne.这将调用Rectangle的一个构造函数,该构造函数将origin初始化为originOneAlso, the constructor sets width to 100 and height to 200.此外,构造函数将width设置为100,将height设置为200。Now there are two references to the same Point object—an object can have multiple references to it, as shown in the next figure:现在有两个对同一Point object的引用—一个对象可以有多个引用,如下图所示:

Now the rectangle's origin variable also points to the Point.

The following line of code calls the Rectangle constructor that requires two integer arguments, which provide the initial values for width and height.下面的代码行调用Rectangle构造函数,该构造函数需要两个整数参数,它们提供widthheight的初始值。If you inspect the code within the constructor, you will see that it creates a new Point object whose x and y values are initialized to 0:如果在构造函数中检查代码,您将看到它创建了一个新的Point对象,其xy值初始化为0:

Rectangle rectTwo = new Rectangle(50, 100);

The Rectangle constructor used in the following statement doesn't take any arguments, so it's called a no-argument constructor:以下语句中使用的Rectangle构造函数不接受任何参数,因此称为无参数构造函数

Rectangle rect = new Rectangle();

All classes have at least one constructor.所有类都至少有一个构造函数。If a class does not explicitly declare any, the Java compiler automatically provides a no-argument constructor, called the default constructor.如果类没有显式声明,Java编译器会自动提供一个无参数构造函数,称为默认构造函数This default constructor calls the class parent's no-argument constructor, or the Object constructor if the class has no other parent.此默认构造函数调用类父级的无参数构造函数,如果类没有其他父级,则调用Object构造函数。If the parent has no constructor (Object does have one), the compiler will reject the program.如果父级没有构造函数(Object确实有构造函数),编译器将拒绝该程序。


Previous page: Objects
Next page: Using Objects