Java基础——接口
1、抽象类和抽象方法:只给出方法的声明而没有具体实现的方法称为抽象方法,且必须使用abstract描述。拥有抽象方法的类为抽象类,同样必须声明为abstract的。不过允许没有抽象方法但声明为abstract的类。而abstract直接功能就是禁止对应类生成相应对象。
2、接口:是一种特殊的抽象类,其所有的方法必须为抽象方法,允许对其进行一切有关抽象类的操作。同时,其允许多重继承,而使其能够向上转型为多个接口类(主要的作用)。
- 允许的特殊的操作:使用抽象类implements(不允许extends)(多个)接口但不实现任何方法;接口extends(不允许implements)(多个)接口。
- 访问权限控制:1)类:允许public和不显示控制,除内部类等特殊情况之外不允许使用其他限定符;2)方法:接口中的方法将自动且强制的转换为public。不过方法受到类访问权限的限制。3)域:将自动且强制的转换为 public static final。因此不允许使用空final但可以使用非常量表达式进行赋值。
3、嵌套接口
class A{
interface B{
void f();
}
public class BImp implements B{
public void f(){}
}
private class BImp2 implements B{
public void f(){}
}
interface C{
void f();
}
public class CImp implements C{
public void f(){}
}
private class CImp2 implements C{
public void f(){}
}
private interface D{
void f();
}
private class DImp implements D{
public void f(){}
}
public class DImp2 implements D{
public void f(){}
}
public D getD(){return new DImp2();}
private D dRef;
public void receiveD(D d){
dRef = d;
dRef.f();
}
}
interface E{
interface G{
void f();
}
// Redundant "public"
public interface H{
void f();
}
void g();
// Can't be private within an interface:
//! private interface I{}
}
public class NestingInterfaces{
public class BImp implements A.B{
public void f(){}
}
class CImp implements A.C{
public void f(){}
}
// Can't implement a private interface except
// within that interface's defining class:
//! class DImp implement A.D{
//! public void f(){}
//! }
public static void main(String[] args){
A a = new A();
// Can't access A.D
//! A.D ad = a.getD();
// Doesn't return anything but A.D
//! A.DImp2 di2 = a.getD();
// Can't access a member of the interface
//! a.getD().f();
// Only another A can do anything with getD():
A a2 = new A();
a2.receiveD(a.getD());
}
}
编译出的文件如下:
只能通过public方法去访问其中的private元素。
恰当的原则应该是:优先选择类而不是接口。从类开始,如果接口的必需性变得非常明确,那么就进行重构。接口是一种重要的工具,但是它容易被滥用。
4、在Java SE 8之后,允许在接口中定义并实现静态方法(且通常的做法是将静态方法放在伴随类中,比如Collection/Collections)和默认方法(必须使用default进行标记,其简化了当只需要接口中的某几个函数而不必实现所有方法的麻烦,并且针对接口扩展的情况,使得之前编写的代码同样可以使用)。
但是这也造成了与C++多重继承相同的二义性,Java首先保证在方法相同时,有限使用超类的方法。但如果接口中存在冲突,那么必须又程序员重载这个方法,从而解决二义性。
5、接口与回调
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class TimerTest{
public static void main(String[] args){
ActionListener listener = new TimePrinter();
Timer t = new Timer(10000, listener);
t.start();
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit(0);
}
}
class TimePrinter implements ActionListener{
public void actionPerformed(ActionEvent event){
System.out.println("At the tone, the timer is " + new Date());
Toolkit.getDefaultToolkit().beep();
}
}/* Output
At the tone, the timer is Tue May 29 11:39:03 GMT+08:00 2018
At the tone, the timer is Tue May 29 11:39:14 GMT+08:00 2018
At the tone, the timer is Tue May 29 11:39:24 GMT+08:00 2018
At the tone, the timer is Tue May 29 11:39:34 GMT+08:00 2018
*///:~
程序启动后,会立即显示一个包含“Quit Program?”字样的对话框,随后每10秒输出一条包含对应时间的定时器消息。