马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 回忆一遥远 于 2017-8-16 08:14 编辑
初始化与清理
“不安全”的编程方式已逐渐成为编程代价高昂的主因之一。
初始化和清理(cleanup)正是涉及安全方面的两个问题。
C++ 引入了构造器,并额外提供了“垃圾回收器”。对于不再使用的内存资源,垃圾回收器 能自动将其释放。
接下来将学习 Java 的构造器以及一些其他的组件。
构造器
在 Java 中,通过提供构造器,类的设计者可确保每个对象都会得到初始化。创建对象时,如果其类 具有构造器,Java就会在用户有能力操作对象之前自动调用相应的构造器,从而保证了初始化的进行。
和 C++ 一样,Java 构造器采用与类相同的名称。
一个带构造器的简单类:class Rock{
Rock(){
System.out.println("Rock ");
}
}
public class SimpleConstructor {
public static void main(String[] args){
for(int i = 0; i < 10; i++)
new Rock();
}
}
输出:Rock
Rock
Rock
Rock
Rock
Rock
Rock
Rock
Rock
Rock
现在,在创建对象时,new Rock(); 将会为对象分配存储空间,并调用相应的构造器。这就确保了在操作对象之前,它已经被恰当地初始化了。
接受任何参数的构造器叫做 无参构造器,和其他方法一样,构造器也能带有形式参数,以便指定如何创建对象。
带参数的构造器:class Rock2{
Rock2(int i){
System.out.print("Rock " + i + " ");
}
}
public class SimpleConstructor2 {
public static void main(String[] args){
for(int i = 0; i < 8; i++)
new Rock2(i);
}
}
输出:Rock 0 Rock 1 Rock 2 Rock 3 Rock 4 Rock 5 Rock 6 Rock 7
有了构造器形式参数,就可以在初始化对象时提供实际参数。
上面源码中 Rock2(int) 是 Rock2 类中唯一的构造器,那么编译器将不会允许你以其他任何方式创建 Rock2 对象。
构造器是一种特殊类型的方法,因为它没有返回值。
方法重载
大多数程序设计语言(尤其是 C )要求为每个方法(在这些语言中经常称为函数)都提供一 个独一无二的标识符。所以绝不能用名为print〇的函数显示了整数之后,又用一个名为 print() 的 函数显示浮点数——每个函数都要有唯一的名称。 在 Java (和 C++)里,构造器是强制重载方法名的另一个原因。既然构造器的名字已经由类 名所决定,就只能有一个构造器名。那么要想用多种方式创建一个对象该怎么办呢?假设你要 创建一个类,既可以用标准方式进行初始化,也可以从文件里读取信息来初始化。这就需要两 个构造器:一个默认构造器,另一个取字符串作为形式参数一该字符串表示初始化对象所需 函的文件名称。由于都是构造器,所以它们必须有相同的名字,即类名。为了让方法名相同而形 式参数不同的构造器同时存在,必须用到方法重载。
重载的构造器和重载的方法:class Tree{
int height;
Tree(){
System.out.println("Planting a seedling");
height = 0;
}
Tree(int initialHeight){
height = initialHeight;
System.out.println("Creating new Tree that is " + height + " feet tall");
}
void info(){
System.out.println("tree is " + height + " feet tall");
}
void info(String s){
System.out.println(s + ": Tree is " + height + " feet tall");
}
}
public class OverLoading {
public static void main(String[] args){
for(int i = 0; i < 5; i++){
Tree t = new Tree(i);
t.info();
t.info("overloaded method");
}
new Tree();
}
}
输出:Creating new Tree that is 0 feet tall
tree is 0 feet tall
overloaded method: Tree is 0 feet tall
Creating new Tree that is 1 feet tall
tree is 1 feet tall
overloaded method: Tree is 1 feet tall
Creating new Tree that is 2 feet tall
tree is 2 feet tall
overloaded method: Tree is 2 feet tall
Creating new Tree that is 3 feet tall
tree is 3 feet tall
overloaded method: Tree is 3 feet tall
Creating new Tree that is 4 feet tall
tree is 4 feet tall
overloaded method: Tree is 4 feet tall
Planting a seedling
创建 Tree 对象的时候,既可以不含参数,也可以用树的髙度当参数。
每个重载的方法都必须有一个独一无二的参数类型列表。这也是 Java 识别不同方法的方式。
参数顺序的不同也足以区分两个方法。一般情况下别这么做,因为这会使代码难以维护。
无参构造器
它的作用是创建一个 “默认对象”。如果你写的类中没有构造器,则编译器会自动帮你创建一个默认构造器。
如果已经定义了一个构造器(无论是否有参数),编译器就不会帮你自动创建默认构造器。
例如:class Bird{
Bird(int i){}
Bird(double d){}
}
public class NoSynthesis {
public static void main(String[] args){
//Bird b = new Bird(); 这么写会报错
Bird b1 = new Bird(1);
Bird b2 = new Bird(1.0);
}
}
要这样写:
new Bird2()
编译器就会报错:没有找到匹配的构造器。
this 关键字
假设你希望在方法的内部获得对当前对象的引用。由于这个引用是由编译器“偷偷”传入的,所以没有标识符可用。但是,为此有个专门的关键字:this。this 关键字只能在方法内部使 用,表示对“调用方法的那个对象”的引用。this 的用法和其他对象引用并无不同。但要注意, 如果在方法内部调用同一个类的另一个方法,就不必使用this,直接调用即可。当前方法中的 this 引用会自动应用于同一类中的其他方法。
当需要明确指出对当前对象的引用时,才需要使用this关键字。
例如:public class Leaf{
int i = 0;
Leaf increment(){
i++;
return this;
}
}
在构造器中调用构造器
this 本身表示对当前对象的引用。
在构造器中如果给 this 添加了参数列表,这会对符合此参数列表的某个构造器调用
例如:public class Test {
int num;
String s = "初始值";
Test(int temp){
num = temp;
System.out.println("num = " + num);
}
Test(String temp){
System.out.println("s = " + temp);
s = temp;
}
Test(String s, int n){
this(n);
// 构造器中调用构造器!
this.s = s;
System.out.println("String and int args");
}
void Pain(){
System.out.println("num = " + num + " s = " + s);
}
public static void main(String[] args) {
new Test("oh", 76);
}
}
输出:num = 76
String and int args
this 可以调用一个构造器,却不能调用两个
构造器调用必须置于起始位置,否则会报错
static 的含义
static 方法没有 this 方法。
在 static 方法中不能调用非静态方法(非静态方法可以调用静态方法)
static 方法很像全局变量,它可以访问其他 static 方法和 static 域
|