主题:Java的对象、接口与包[
对象、接口与包
对类实例化,可以生成多个对象,通过这些对象之间的消息传递进行交互,可完成很复杂的功能。一个对象的生命周期分为令个阶段:生成、使用和清除。
1.对象的生成
对象是一组相关变量和相关方法的封装体,是类的一个实例。对象的特征是对象的行为、状态和身份。对象生成包括声明、实例化和初始化三方面内容。一般格式是先定义一个对象变量,再用关键字new生成一个对象,并为对象中的变量赋初始值矛如下所示:
123大学生网 http://www.123daxuesheng.com
type objectName=new type([参数]);
其中:type objectName声明是定义对象的类型,它包括类和接口的复合类型。new关键字是实例化一个对象,给对象分配内存,它调用对象的构造方法,
下面是关于对象使用的综合使用的程序片段:
{ public static void main(String[]args)
{ BankAccount account=new BankAccount(10000); //定义对象
account.start(10); //调用对象的成员方法
…
}
}
class BankAccount
{ …
public void start(double rate)
{ ActionListener adder=new InterestAdder(rate); //方法中使用对象
Timer t=new Timer(1000,adder); //对象adder作参数
t.start(); //调用对象的方法
}
…
}
从上面程序段看出,用BankAccount account=new BankAccount(10000);生成BankAccount类的对象。ccount后,就可以用account.start(10)来调用方法。而在start()方法中定义对象adder作为Timer()方法的参数,可以用new生成对象的引用,再调用它的方法。
3.对象的清除
对象的清除指释放对象所占用的内存。Java语言有自动收集垃圾功能,会周期性地回收一些长期不用的对象占用的内存,因此,编写程序时无需对内存的使用操心。但是,自动收集垃圾操作的优先级较低,允许有其他一些办法释放对象所占用的内存。归纳起来对象清除的途径为:
(1)依靠Java的垃圾回收机制回收内存。
(2)调用System.gc(),请求垃圾回收。
(3)Java系统开始运行时,自动调用Java.lang.Object.finalize()释放内存。
(4)在程序中调用重写的finalize()释放系统资源,其格式为:
protected void finalize() throws throwable{
…
super.finalize();
}
通常要用super来调用基类的finalize()方法,可参见5.1.3节中的类继承。
4.接口
接口是一种只含有抽象方法或常量的一种特殊的抽象类。因此,首先讨论一下抽象类的概念。在Java语言中,用abstract修饰符定义的类称为抽象类,在其中的方法称为抽象方法。abstract类必须被继承,abstract方法必须被重写,abstract类不能实例化。abstract类的格式为:
abstract class abstractClass{
…
}
接口是不包含成员变量和方法实现的抽象类,它只包含常量和方法的定义。接口的主要功能是:
(1)不管类的层次,可实现互不相关的类具有相同的行为。
(2)通过接口说明多个类所需实现的方法。
(3)通过接口可以了解对象的交互界面,无需了解对象所对应的类。
接口定义由接口声明和接口体组成。程序中的接口定义写成:
interface ActionListener //接口声明
{ void actionPerformed(ActionEvent); //方法定义
}
这里省略了前面的修饰符:public abstract,因为这是所有接口中的方法的默认值。
而在Java类库中表示为:
class java.awt.event.ActionListener
{
public abstract actionPerformed(Java.awt.event.ActionEvent);
}
接口的实现用关键字implements,这里接口中的抽象方法actionPerformed()被赋予具体的含义。程序片段如下所示:
private class InterestAdder implements ActionListener
{ …
public void actionPerformed(ActionEvent event)
{ double interest=balance*rate/100
balance+=interest;
NumberFormat formatter=NumberFormat.getCurrencyInstance();
System.out.println("balance="+formatter.format(balance));
}
private double rate;
}
接口可以作为一种引用类型来使用。用接口类型变量将实现该接口的类的实例存入,通过这些变量去访问类所实现接口中的方法。这样,与对象所对应的类可以无需了解,而把重点放在交互界面上。
接口不仅是抽象类,其用途胜于抽象类。因为,接口不包括任何实现,所以与存储空间没有任何关系。将多个接口合并,即多重继承就可以很容易实现。请看下面的程序段:
//多个接口合并
interface CanFight { void fight();}
interface CanSwim { void swim();}
interface CanFly { void fly();}
class ActionCharacter{ public void fight(){}}
class Hero extends ActionCharacter implements CanFight.CanSwim.CanFly
public void swim() {}
public void fly() {}
}
puhlic class Adventure {
public static void t(CanFight x){ x.fight();}
public static void u(CanSwim x){ x.swim();}
public static void v( CanFly x){ x.fly();}
public static void w(ActionCharacter x){ x.fight();}
puhlic static void main(String[]args){
Hero h=new Hero();
t(h); //视为CanFight接口
u(h); //视为CanSwim接口
v(h); //视为CanFly接口
w(h); //视为ActionCharacter接口
}
}
上面Hero类从ActionCharacter类扩展,利用implements将CanFight、CanSwim和CanFly接口合并。这里,Hero并没有去定义fight(),但ActionCharacter有fight()的定义,Hero继承下来。在Adventure类中,有4个方法:t()、u()、v()、w(),接受不同接口参数。一旦Hero对象生成,可被传送到这4个方法中的任意一个。实际上,就是把该对象向上转型至对应的接口。由此得知,如果父类可以不带任何方法和变量定义时,应该选用接口而不用抽象类。
5.包
在Java语言中,每个类生成一个字节文件,该文件名与类名相同。这样,同名类会发生冲突。为解决此矛盾,Java采用包来管理类名空间。包为编程提供了一种命名机制,也是一种可见性限制的机制,还是面向对象方法的封装机制。包将类和接口封装在一起,便于大量类和接口的管理,并有利于类和接口的安全。
定义一个包要用package关键字。例如:将各个类置于文件夹。com.cwch.gzb中,且每一个类的起始语句为:
package com.cwch.gzb;
…
public class Employee
{ … }
提示:用package语句说明一个包时,该包的层次结构必须与文件目录的层次相同。否则,在编译时可能出现查找不到的问题。
使用一个包中的类时,首先要用关被字import导入这些类所在的包。例如:
import com.cwch.gzb.*; //雇员信息包
public class PackageTest
{ public static void main(String[]args)
{ Employee harry=new Employee("李明",50000,l989,10,1);
…
}
}
当包中有相同名字的类,使用其中类时,不用import导入,而是直接用带包名的方法使用。例如:Date类在java.util包中,可编写直接引入类:
class myDate extends java.util.Date
{
…
}
提示:Java语言的Java.lang包是编译器自动导入的。因此,编程时使用该包中的类,可省去import导入。但使用其他包中的类,必须用import导入
对类实例化,可以生成多个对象,通过这些对象之间的消息传递进行交互,可完成很复杂的功能。一个对象的生命周期分为令个阶段:生成、使用和清除。
1.对象的生成
对象是一组相关变量和相关方法的封装体,是类的一个实例。对象的特征是对象的行为、状态和身份。对象生成包括声明、实例化和初始化三方面内容。一般格式是先定义一个对象变量,再用关键字new生成一个对象,并为对象中的变量赋初始值矛如下所示:
123大学生网 http://www.123daxuesheng.com
type objectName=new type([参数]);
其中:type objectName声明是定义对象的类型,它包括类和接口的复合类型。new关键字是实例化一个对象,给对象分配内存,它调用对象的构造方法,
下面是关于对象使用的综合使用的程序片段:
{ public static void main(String[]args)
{ BankAccount account=new BankAccount(10000); //定义对象
account.start(10); //调用对象的成员方法
…
}
}
class BankAccount
{ …
public void start(double rate)
{ ActionListener adder=new InterestAdder(rate); //方法中使用对象
Timer t=new Timer(1000,adder); //对象adder作参数
t.start(); //调用对象的方法
}
…
}
从上面程序段看出,用BankAccount account=new BankAccount(10000);生成BankAccount类的对象。ccount后,就可以用account.start(10)来调用方法。而在start()方法中定义对象adder作为Timer()方法的参数,可以用new生成对象的引用,再调用它的方法。
3.对象的清除
对象的清除指释放对象所占用的内存。Java语言有自动收集垃圾功能,会周期性地回收一些长期不用的对象占用的内存,因此,编写程序时无需对内存的使用操心。但是,自动收集垃圾操作的优先级较低,允许有其他一些办法释放对象所占用的内存。归纳起来对象清除的途径为:
(1)依靠Java的垃圾回收机制回收内存。
(2)调用System.gc(),请求垃圾回收。
(3)Java系统开始运行时,自动调用Java.lang.Object.finalize()释放内存。
(4)在程序中调用重写的finalize()释放系统资源,其格式为:
protected void finalize() throws throwable{
…
super.finalize();
}
通常要用super来调用基类的finalize()方法,可参见5.1.3节中的类继承。
4.接口
接口是一种只含有抽象方法或常量的一种特殊的抽象类。因此,首先讨论一下抽象类的概念。在Java语言中,用abstract修饰符定义的类称为抽象类,在其中的方法称为抽象方法。abstract类必须被继承,abstract方法必须被重写,abstract类不能实例化。abstract类的格式为:
abstract class abstractClass{
…
}
接口是不包含成员变量和方法实现的抽象类,它只包含常量和方法的定义。接口的主要功能是:
(1)不管类的层次,可实现互不相关的类具有相同的行为。
(2)通过接口说明多个类所需实现的方法。
(3)通过接口可以了解对象的交互界面,无需了解对象所对应的类。
接口定义由接口声明和接口体组成。程序中的接口定义写成:
interface ActionListener //接口声明
{ void actionPerformed(ActionEvent); //方法定义
}
这里省略了前面的修饰符:public abstract,因为这是所有接口中的方法的默认值。
而在Java类库中表示为:
class java.awt.event.ActionListener
{
public abstract actionPerformed(Java.awt.event.ActionEvent);
}
接口的实现用关键字implements,这里接口中的抽象方法actionPerformed()被赋予具体的含义。程序片段如下所示:
private class InterestAdder implements ActionListener
{ …
public void actionPerformed(ActionEvent event)
{ double interest=balance*rate/100
balance+=interest;
NumberFormat formatter=NumberFormat.getCurrencyInstance();
System.out.println("balance="+formatter.format(balance));
}
private double rate;
}
接口可以作为一种引用类型来使用。用接口类型变量将实现该接口的类的实例存入,通过这些变量去访问类所实现接口中的方法。这样,与对象所对应的类可以无需了解,而把重点放在交互界面上。
接口不仅是抽象类,其用途胜于抽象类。因为,接口不包括任何实现,所以与存储空间没有任何关系。将多个接口合并,即多重继承就可以很容易实现。请看下面的程序段:
//多个接口合并
interface CanFight { void fight();}
interface CanSwim { void swim();}
interface CanFly { void fly();}
class ActionCharacter{ public void fight(){}}
class Hero extends ActionCharacter implements CanFight.CanSwim.CanFly
public void swim() {}
public void fly() {}
}
puhlic class Adventure {
public static void t(CanFight x){ x.fight();}
public static void u(CanSwim x){ x.swim();}
public static void v( CanFly x){ x.fly();}
public static void w(ActionCharacter x){ x.fight();}
puhlic static void main(String[]args){
Hero h=new Hero();
t(h); //视为CanFight接口
u(h); //视为CanSwim接口
v(h); //视为CanFly接口
w(h); //视为ActionCharacter接口
}
}
上面Hero类从ActionCharacter类扩展,利用implements将CanFight、CanSwim和CanFly接口合并。这里,Hero并没有去定义fight(),但ActionCharacter有fight()的定义,Hero继承下来。在Adventure类中,有4个方法:t()、u()、v()、w(),接受不同接口参数。一旦Hero对象生成,可被传送到这4个方法中的任意一个。实际上,就是把该对象向上转型至对应的接口。由此得知,如果父类可以不带任何方法和变量定义时,应该选用接口而不用抽象类。
5.包
在Java语言中,每个类生成一个字节文件,该文件名与类名相同。这样,同名类会发生冲突。为解决此矛盾,Java采用包来管理类名空间。包为编程提供了一种命名机制,也是一种可见性限制的机制,还是面向对象方法的封装机制。包将类和接口封装在一起,便于大量类和接口的管理,并有利于类和接口的安全。
定义一个包要用package关键字。例如:将各个类置于文件夹。com.cwch.gzb中,且每一个类的起始语句为:
package com.cwch.gzb;
…
public class Employee
{ … }
提示:用package语句说明一个包时,该包的层次结构必须与文件目录的层次相同。否则,在编译时可能出现查找不到的问题。
使用一个包中的类时,首先要用关被字import导入这些类所在的包。例如:
import com.cwch.gzb.*; //雇员信息包
public class PackageTest
{ public static void main(String[]args)
{ Employee harry=new Employee("李明",50000,l989,10,1);
…
}
}
当包中有相同名字的类,使用其中类时,不用import导入,而是直接用带包名的方法使用。例如:Date类在java.util包中,可编写直接引入类:
class myDate extends java.util.Date
{
…
}
提示:Java语言的Java.lang包是编译器自动导入的。因此,编程时使用该包中的类,可省去import导入。但使用其他包中的类,必须用import导入