用构造器确保初始化
初始化和清理是涉及安全的两个问题。
在java中引入了构造器的概念。并且额外的提供了GC(垃圾回收器)。
可以假想为编写的每个类都定义了一个初始化方法。该方法的名称提醒自己在使用其对象之前,应该首先调用初始化方法,然而这同时意味着用户必须记得自己去调用此方法。在java中,通过提供构造器,类的设计者可确保每个对象都会得到初始化。创建对象时,如果其类具有构造器,java就会在用户有能力操作对象之前自动调用相应的构造器,从而保证了初始化的进行。
构造器的命名:在java中,构造器的名字和类名是相同的。**不接受任何参数的构造器叫默认构造器**。
java术语叫做无参构造器
构造器是一种特殊类型的方法,因为它没有返回值。这与void有明显的区别。
方法重载
任何程序设计语言都具备的一项重要特性就是对名字的运用。当创建一个对象时,也就给此对象分配到的存储空间取了一个名字。所谓的方法就是给某个动作取的名字。通过使用名字,可以引用所有的对象和方法。
重载方法的特征:相同的方法名、不同的参数列表。
默认构造器
如上所诉,默认构造器是没有形式参数的——它的作用是创建一个“默认对象”。如果类中没有构造器,则编译器会自动帮你创建一个默认构造器。如果已经手动创建了一个构造器之后,编译器则不会帮你创建构造器了。
this关键字
C c1 = new C();
c2 = new C();
c1.a(1);
c2.a(2);
怎么让a()知道是是c1调用了它还是c2调用的它。
为了能用简便、面向对象的语法来编写代码——即“发送消息给对象”,编译器其实做了一些幕后的工作。它悄悄的把“所操作对象的引用”作为第一个参数给了a()。所以其实是这样的:
C.a(c1,1);
C.a(c2,2);
这是内部的表现形式,如果我们这样写,编译器并不能通过验证;但是这样的写法确实可以解决不少问题。
假设你希望在方法的内部获得对当前对象的引用。由于这个引用是编译器悄悄给的,所以没有标识符可用。
但是为此有个专门的关键字:this。this关键字只能在方法的内部使用,表示对“调用方法的那个对象”
的引用。this的用法和其他对象引用并无不同。但要注意如果在方法内部调用同一个类的另一个方法,
就不必用this了,可以直接调用。
在构造器中调用构造器
可能为一个类写了多个构造器,有时可能在一个构造器中调用另一个构造器,以免重复代码。
可用this关键字做到这一点。
通常写this的时候,都是指“这个对象”或者“当前对象”,而且它本身表示对当前对象的引用。
如果在构造器中,为this添加了参数列表,那么就有了不同的含义。这将产生对符合此参数列表的某个构造器的明确调用;这样调用其他构造器就有了直接的途径。
public class Flower{
int petalCount = 0;
String s = "initial value";
Flower(int petals){
petalCount = petals;
print("petalCount= " + petalCount);
}
Flower(String ss){
print("s= " + ss);
}
Flower(String s, int petals){
this(petals);
this.s = s;
print("String & int args");
}
Flower(){
this("hi" , 47);
print("default constructor (no args)");
}
void printPetalCount(){
print("petalCount = " + petalCount + " s = " +s);
}
public static void main(String[] args){
Flower x = new Flower();
x.printPetalCount();
}
}
/**
* output:
* petalCount= 47
* String & int args
* default constructor (no args)
* petalCount = 47 s = hi
*/
构造器Flower(String s,int petals)表明:尽管可以用this调用一个构造器,但却不能调用两个。
此外,必须将构造器调用置于起始位置处,否则编译器会报错。
这个例子也展示了this的另一种用法。由于参数s的名称和数据成员s的名字相同,所以会产生歧义。
使用this.s来代表数据成员就能解决这个问题。在java中会经常出现这样的用法。
下章会将到static和清理,以上内容如有问题,欢迎指出。