AP CSA 1.13:创建和初始化对象:构造器
In the previous lesson, we learned that objects are instances of classes. In this lesson, we learn how objects are created and initialized using constructors.
上一课我们学习了对象是类的实例。这一课,我们学习如何使用构造器创建并初始化对象。
A constructor is called with
newto create an object and initialize its attributes. 构造器通过new被调用,用来创建对象并初始化对象的属性。
Core Concepts:
核心知识点
1. Main Idea
核心理解
A constructor is used to create and initialize a new object.
构造器(constructor) 用来创建并初始化一个新对象。
The general syntax is:
基本语法是:
ClassName variableName = new ClassName(arguments);
Example:
World habitat = new World();
Turtle yertle = new Turtle(habitat);
new World() creates a new World object.
new Turtle(habitat) creates a new Turtle object inside the world.
new World() 创建一个新的 World 对象。
new Turtle(habitat) 在这个世界中创建一个新的 Turtle 对象。
2. Constructors Match the Class Name
构造器名字和类名相同
A constructor has the same name as the class.
构造器的名字和类名相同。
Example:
public class Date
{
private int year;
private int month;
private int day;
public Date()
{
// implementation not shown
}
public Date(int y, int m, int d)
{
// implementation not shown
}
}
Here, both constructors are named Date because the class is named Date.
这里两个构造器都叫 Date,因为类名是 Date。
Important AP point:
AP 重点:
constructor name = class name
3. Object Creation Syntax
对象创建语法
To create an object, you usually need both:
创建对象时,通常需要这两部分:
-
the keyword
new -
a constructor call
-
关键字
new -
构造器调用
Correct:
World w = new World();
World w2 = new World(300, 500);
Wrong:
World w = new World;
World w = World();
Why?
为什么?
| Code | Problem |
|---|---|
new World |
missing parentheses |
World() |
missing new |
World w = null; |
valid declaration, but no object is created |
World w = null; is legal Java, but it does not create a World object.
World w = null; 是合法的 Java 代码,但它没有创建 World 对象。
4. Constructor Overloading
构造器重载
A class can have more than one constructor.
一个类可以有多个构造器。
This is called constructor overloading.
这叫 构造器重载(constructor overloading)。
Example:
World world1 = new World();
World world2 = new World(300, 400);
These constructor calls match different constructor signatures:
这些构造器调用匹配不同的构造器签名:
| Constructor Call | Meaning |
|---|---|
new World() |
create a default-size world |
new World(300, 400) |
create a world with width 300 and height 400 |
A no-argument constructor has no arguments inside the parentheses.
无参构造器的括号里没有实参。
new World()
It often sets attributes to default values.
它通常会把对象的属性设置为默认值。
5. Constructor Signatures
构造器签名
A constructor signature consists of:
构造器签名由这两部分组成:
constructor name + ordered list of parameter types
也就是:
构造器名字 + 按顺序排列的参数类型列表
Example:
public Date()
{
}
public Date(int year, int month, int day)
{
}
The constructor signatures are:
Date()
Date(int, int, int)
Constructor signatures do not use variable names when matching calls. The important part is the constructor name and the ordered parameter types.
匹配构造器调用时,重点不是变量名,而是构造器名字和按顺序排列的参数类型。
6. Matching Arguments to Constructors
匹配实参与构造器
Constructor arguments must match the constructor signature in:
构造器实参必须和构造器签名匹配:
-
number
-
order
-
compatible type
-
数量
-
顺序
-
兼容的数据类型
Example:
World world1 = new World(300, 400);
Turtle t = new Turtle(50, 100, world1);
If the Turtle constructor expects:
Turtle(int x, int y, World world)
then this is correct:
Turtle t = new Turtle(50, 100, world1);
This is wrong:
Turtle t = new Turtle(world1, 50, 100);
The order does not match the constructor signature.
实参顺序和构造器签名不匹配。
7. Parameters and Arguments
参数与实参
A parameter is a variable in the constructor header.
参数(parameter) 是构造器头中的变量。
An argument is the value passed into the constructor call.
实参(argument) 是调用构造器时传入的值。
Example:
public World(int width, int height)
{
// implementation not shown
}
World w = new World(150, 200);
Here:
| Item | Role |
|---|---|
width |
parameter |
height |
parameter |
150 |
argument |
200 |
argument |
When the constructor is called:
width gets 150
height gets 200
调用构造器时:
width 得到 150
height 得到 200
Java uses call by value, so the parameters receive copies of the argument values.
Java 使用 按值传递(call by value),所以参数接收的是实参值的副本。
8. Object References and null
对象引用与 null
A variable of a class type stores an object reference.
类类型变量存储的是对象引用。
You can think of an object reference as a way to find the object in memory.
可以把对象引用理解成找到对象的“内存地址”。
World world1 = new World();
Turtle t1 = new Turtle(world1);
A reference variable can also store null.
引用变量也可以存储 null。
Turtle t1 = null;
This means:
t1 does not refer to any Turtle object yet.
意思是:
t1 目前没有指向任何 Turtle 对象。
Later, it can refer to a real object:
之后,它可以指向一个真正的对象:
t1 = new Turtle(world1);
9. Reading a Class Definition
读懂类定义
AP CSA questions may show you a class and ask which constructor call is valid.
AP CSA 题目可能会给你一个类定义,让你判断哪个构造器调用是合法的。
Example:
public class Cat
{
private String color;
private String breed;
private boolean isHungry;
public Cat()
{
color = "unknown";
breed = "unknown";
isHungry = false;
}
public Cat(String c, String b, boolean h)
{
color = c;
breed = b;
isHungry = h;
}
}
Valid constructor calls:
Cat a = new Cat();
Cat c = new Cat("orange", "Tabby", false);
Invalid constructor call:
Cat b = new Cat("Shorthair", true);
Why?
为什么?
There is no constructor with the signature:
Cat(String, boolean)
这个类中没有 Cat(String, boolean) 这个构造器签名。
10. Common Beginner Mistakes
常见初学者错误
| Mistake | Wrong Code | Why Wrong | Correct Code | 中文解释 |
|---|---|---|---|---|
Missing new |
World w = World(); |
constructor calls that create objects need new |
World w = new World(); |
创建对象要用 new |
| Missing parentheses | World w = new World; |
constructor call needs () |
World w = new World(); |
构造器调用要有括号 |
| Wrong argument order | new Turtle(world1, 50, 100) |
order does not match expected signature | new Turtle(50, 100, world1) |
实参顺序必须匹配 |
| Wrong number of arguments | new Cat("Tabby", true) |
no matching constructor | new Cat("orange", "Tabby", false) |
实参数量不匹配 |
| Confusing parameter and argument | saying 150 is a parameter |
150 is passed in the call |
150 is an argument |
参数在构造器头,实参在调用里 |
Thinking null creates an object |
Turtle t = null; |
null means no object |
Turtle t = new Turtle(world1); |
null 不创建对象 |
11. Debugging Example
调试例子
Buggy code:
public class TurtleConstructorDebug
{
public static void main(String[] args)
{
World w = new World(300, 300);
Turtle t1 = new Turtle();
Turtle t2 = new Turtle(w, 100, 50);
t1.forward();
t2.turnLeft();
w.show(true);
}
}
Problems:
new Turtle()is invalid if the Turtle constructor requires aWorld.new Turtle(w, 100, 50)has the wrong argument order if the expected signature isTurtle(int x, int y, World world).
问题:
- 如果 Turtle 构造器需要一个
World,那么new Turtle()不合法。 - 如果构造器签名是
Turtle(int x, int y, World world),那么new Turtle(w, 100, 50)的实参顺序错误。
Fixed code:
public class TurtleConstructorDebug
{
public static void main(String[] args)
{
World w = new World(300, 300);
Turtle t1 = new Turtle(w);
Turtle t2 = new Turtle(100, 50, w);
t1.forward();
t2.turnLeft();
w.show(true);
}
}
| Bug | Type | Fix |
|---|---|---|
new Turtle() |
compile-time error | use new Turtle(w) |
new Turtle(w, 100, 50) |
compile-time error | use new Turtle(100, 50, w) |
| missing semicolon after object creation | compile-time error | end statement with ; |
12. Mini Practice
小练习
Practice 1: Valid Syntax
练习 1:判断合法语法
Which lines correctly create or initialize a World reference?
A. World w = null;
B. World w = new World;
C. World w = new World();
D. World w = World();
E. World w = new World(300, 500);
Answer:
A, C, and E
Explanation: null is a valid reference value, but it does not create an object. new World() and new World(300, 500) call constructors correctly.
解释:null 是合法的引用值,但不创建对象。new World() 和 new World(300, 500) 正确调用了构造器。
Practice 2: Parameters or Arguments?
练习 2:参数还是实参?
In this constructor header:
public World(int width, int height)
What are width and height?
Answer:
parameters
解释:
它们是参数,因为它们出现在构造器头中。
In this constructor call:
new World(150, 200)
What are 150 and 200?
Answer:
arguments
解释:
它们是实参,因为它们是在调用构造器时传入的值。
Practice 3: Match the Constructor
练习 3:匹配构造器
Given this class:
public class Movie
{
public Movie(String t, String d, double r)
{
// implementation not shown
}
public Movie(String t)
{
// implementation not shown
}
}
Which code constructs a Movie object with title "Lion King" and rating 8.0?
A. Movie m = new Movie(8.0, "Lion King");
B. Movie m = Movie("Lion King", 8.0);
C. Movie m = new Movie();
D. Movie m = new Movie("Lion King", "Disney", 8.0);
E. Movie m = new Movie("Lion King");
Answer:
D. Movie m = new Movie("Lion King", "Disney", 8.0);
Explanation: this matches the constructor signature Movie(String, String, double).
解释:这个调用匹配 Movie(String, String, double) 这个构造器签名。
Practice 4: Fix the Code
练习 4:修复代码
Fix the constructor call.
World world1 = new World(300, 400);
Turtle t = new Turtle(world1, 50, 100);
Assume the constructor signature is:
Turtle(int x, int y, World world)
Fixed code:
World world1 = new World(300, 400);
Turtle t = new Turtle(50, 100, world1);
Explanation: the arguments must match the constructor signature in number, order, and type.
解释:实参必须在数量、顺序和类型上匹配构造器签名。
Quick Checklist
快速检查清单
Before answering a constructor question, check:
做构造器题目前,检查:
- Is the object being created with
new? - Does the constructor name match the class name?
- Are parentheses included after the constructor name?
- Which constructor signatures are available?
- Is this a no-argument constructor or a constructor with parameters?
- Do the arguments match the constructor signature?
- Do the argument number, order, and types match?
- Are you confusing parameters with arguments?
- Is the variable a reference type variable?
- Does
nullmean “no object”? - Is the constructor overloaded?
- If multiple constructors exist, which one matches the call?