【JAVA核心技术卷一】Interface 接口

来源:互联网 发布:java窗口程序 编辑:程序博客网 时间:2024/06/05 03:25

Interface 接口

  • Interface接口
  • Clone克隆
  • Callback回调

接口(interface)主要用来描述类具有什么功能,而不是给出每个功能的具体实现。一个类可以实现(implement)一个或多个接口,并在需要接口的地方,随时使用实现了相应的对象。

接口不是类,而是对类的一组需求描述

例如:

Arrays类中的sort方法承诺可以对对象数组进行排序,但要求满足一下前提:对象所属的类必须实现了Comparable接口。

public interface Comparable<T>{  int compareTo(T ohter);}

接口中的所有方法自动属于public,因此,在接口中声明方法时,不必提供关键字public接口决不能含有实例域,也不能在接口中实现方法。

为了让类实现一个接口,通常需要下面两个步骤:

  1. 让类声明为实现给定的接口
  2. 对接口中的所有方法进行定义

接口声明中,没有将comparteTo声明为public,这是因为在接口中的所有方法都自动地是public。不过,在实现接口时,必须把方法声明为public;否则,编译器将认为这个方法的访问权限是(default)

接口的特性

接口不是类,不能使用new运算符实例化一个接口

x = new Comparable(...);    //error

却能声明接口的变量

Comparable x;   //ok

接口变量必须引用实现了接口的类对象:

x = new Employee(...); //ok provided Employee implements Comparable

可以使用instanceof检查一个对象是否实现了某个特定的接口

if(anObect instanceof Comparable){    ...}

虽然在接口中不能包含实例域或静态方法,但却可以包含常量

public interface Powered extends Comparable{    int compareTo();    int COMPARE_NUMBER = 80;    //a public static final constant}

Clone 对象克隆

当拷贝一个变量时,原始变量与拷贝变量引用同一个对象。这就是说,改变一个变量所引用的对象将会对另一个变量产生影响。

Employee original = new Employee("John",5000);Employee copy = original;copy.raiseSalary(10);   //also changed original

如果创建一个对象的新的copy,他的最初状态与original一样,但以后将可以各自改变各自的状态,那就需要使用clone方法

Employy copy = original.clone();copy.raiseSalary(10);   //original unchanged

clone方法是Object的一个protected方法,也就是说,在用户编写的代码中不能直接调用它。只有Employee类才能够克隆Employee对象。但是,如果在对象中包含了子对象的引用,拷贝的结果会使得两个域引用同一个子对象,因此原始对象与克隆对象共享这部分信息。

对于每一个类,都需要做出下列判断:

  1. 实现Cloneable接口
  2. 使用public访问修饰符重新定义clone方法

如果一个对象需要克隆,而没有实现Cloneable接口,就会产生一个已检验异常(checked exception

Cloneable接口是Java提供的几个标记接口(tagging interface)之一。通常使用接口是为了实现某个或某组特定的方法,而标记接口没有方法,只是为了表明它属于一个特定的类型

即使clone的默认实现(浅拷贝)能够满足需求,也应该实现Cloneable接口,将clone重定义为public,并调用super.clone()

class Employee implements Cloneable{    public Employee clone() throws CloneNotSupprtedExcetion{        return (Employee)super.clone();    }}

刚刚的clone方法只是将这个方法声明为public。为了实现深拷贝,必须克隆所有可变的实例域

class Employee implements Cloneable{    public Employee clone() throws CloneNotSupprtedExcetion{        //call Object.clone()        Employee cloned = (Employee) super.clone();        //clone mutable fields        cloned.hireDay = (Date)hireDay.clone();        return cloned;    }}

只要在clone中含有没有实现Cloneable接口的对象,Object类的clone方法就会抛出一个CloneNotSupportException异常。当然,EmployeeDate类都实现了Cloneable接口,因此不会抛出异常。但是编译器并不知道这些情况,因此需要声明异常

public Employee clone() throws CloneNotSupprtedExcetion

关于捕获异常的写法

try{  return cloned;}catch(CloneNotSupprtedExcetion e){  return null;}

这中写法比较适用于final类,否则最好还是保留throws说明符。如果不支持克隆,子类具有抛出CloneNotSupprtedExcetion异常的选择权

Callback回调

回调(Callback)是一种常见的程序设计模式。在这种模式中,可以指出某个特定事件发生时应该采取的动作。

java.swing包中有一个Timer类,可以使用它在达到给定的时间间隔需要做些什么操作。如何告知定时器做什么呢?在很多程序设计语言中,可以提供一个函数名,定时器周期性地调用它。但是,在java标准类库中的类采用的是面向对象方法。它将某个类的对象传递给定时器,然后,定时器调用这个对象的方法。由于对象可以携带一些附加的信息,所以传递一个对象比传递一个函数要灵活得多。

当然,定时器需要知道调用哪一个方法,并要求传递的对象所属的类实现了java.awt.event包的ActionListener接口

public interface ActionListener{  void actionPerformed(ActionEvent event);}

当到达指定的时间间隔,定时器就调用actionPerformed方法。

定义一个实现ActionListener接口的类,然后将需要执行的语句放在actionPerformed方法中

class TimePrinter implements ActionListener{    public void actionPerformed(ActionEvent event){        Date now = new Date();        System.out.println("time is " +now );    }}

接下来,构造这个类的一个对象,并将它传递给Timer构造器

ActionListener listener = new TimePrinter();Timer t = new Timer(10000,listener);

Timer构造器的第一个参数是发出通告的时间间隔,它的单位是毫秒。这里希望每隔10秒通告一次。第二个参数是监听器对象。

最后启动定时器

t.start();

每隔10秒钟,下列信息出现一次:

> time is Tue Sep 29 16:09:53 CST 2015
0 0
原创粉丝点击