Java接口:
接口定义了某一批类需要遵守的规范,接口不关心 这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。
接口是从多个相似类中抽象出来的规范,接口不提供任何实现。
接口体现的是规范和实现分离的设计哲学。(降低耦合度)
一个接口可以有多个父接口,但接口只能继承接口,不能继承类。
由于接口定义的是一种规范,因此接口不能包含构造器和初始化块定义。接口里可以包含成员变量(只能是静态常量)、方法(只能是抽象实例方法、类方法、默认方法或私有方法)、内部类(包含内部接口、枚举)定义。
接口里的常量、方法、内部类和内部枚举都是public访问权限。
定义接口成员时,可以省略访问控制修饰符,如果指定访问控制修饰符,则只能使用public访问控制修饰符。
此处补充Java中default关键字在接口中的用法(挺重要的)
我们本来写Java接口的时候,一般情况下是不能有带方法体的函数。
而default关键字在接口中修饰方法时,方法可以有方法体,来看一个例子。
public interface defaultTest {
default public void test(){
System.out.println("test in interface");
}
}
(注意:此处test()方法有方法体,但是没有报错哦!一旦把default关键字删掉,就会报错!从这里也看出了default关键字的功力)
public class defaultTestImpl implements defaultTest {
@Override
public void test() {
System.out.println("test in Class");
}
public static void main(String[] args){
defaultTest d = new defaultTestImpl();
d.test(); }}
运行结果:
test in Class
我们对接口进行改变,查看运行结果,以便更好理解default关键字的作用:
public interface defaultTest {
default public void test(){
System.out.println("test in interface");
}
default public void doSomething() {
System.out.println("doSomething in interface");
}
}
public class defaultTestImpl implements defaultTest {
@Override
public void test() {
System.out.println("test in Class");
}
public static void main(String[] args){
defaultTest d = new defaultTestImpl();
d.test();
d.doSomething();
}
}
运行结果:
test in Class
doSomething in interface
default关键字可以让接口中的方法可以有默认的函数体。
当一个类实现这个接口时,可以不用必须去实现这个带有default关键字的方法,当然,这个类若实现这个方法,就等于子类覆盖了这个方法,最终运行结果符合Java多态特性。
由于默认方法没有static修饰,因此不能直接使用接口来调用默认方法,需要使用接口的实现类的实例来调用这些默认方法。
Java接口实例,更好体现接口各种函数的权限:
package fang;
public interface Output {
int MAX_CACHE_LINE = 50;
void out();
void getData(String msg);
default void print(String ... msgs) {
for(String msg: msgs) {
System.out.println(msg);
}
}
default void test() {
System.out.println("the default test");
}
//This static method of interface Output can only be accessed as Output.staticTest
static String staticTest() {
System.out.println("static staticTest in interFace");
return "static staticTest in interFace";
}
private void foo() {
System.out.println("private foo");
}
private static void bar() {
System.out.println("bar private static");
}
}
package fang;
interface Product{
int getProductTime();
}
public class Printer implements Output,Product{
private String[] printData = new String [MAX_CACHE_LINE];
private int dataNum=0;
public void out() {
while(dataNum>0) {
System.out.println("打印机打印作业 "+printData[0]);
System.arraycopy(printData, 1, printData, 0, --dataNum);
}
}
public void getData(String msg) {
if(dataNum>= MAX_CACHE_LINE) {
System.out.println("输出队列已满,添加失败");
}
else {
printData[dataNum++]= msg;
//System.out.println(dataNum);
}
}
public int getProductTime() {
return 45;
}
public static void main(String []args)
{
Output o = new Printer();
o.getData("大学数学");
o.getData("大学物理");
o.out();
Output.staticTest();
o.getData("概率论与数理统计");
o.getData("复变函数");
o.out();
o.print("孙悟空","猪八戒","唐僧");
o.test();
Product p= new Printer();
System.out.println(p.getProductTime());
Object obj = p;
}
}
输出结果:
打印机打印作业 大学数学
打印机打印作业 大学物理
static staticTest in interFace
打印机打印作业 概率论与数理统计
打印机打印作业 复变函数
孙悟空
猪八戒
唐僧
the default test
45
Printer类实现了Output接口和Product接口,因此Printer对象既可直接赋给Output变量,也可以直接赋给Product变量。
仿佛Printer类既是Output类的子类,也是Product类的子类,这就是Java提供的模拟多继承!
Java的面向接口编程的工厂模式,将另外开辟一篇博客详细说明!