1、什么是接口
接口可以看做是一个“纯”抽象类,它只提供一种形式,并不提供实现。
接口中可以规定方法的原型 :方法名、参数列表以及返回类型 ,但不规定方法主体 ;也可以包含基本数据类型 的数据成员,但它们都默认为static
和final
。
2、接口的作用
是面向对象的一个重要机制
是继承多个设计
建立了类和类之间的“协议”:
将类根据其实现的功能分组用接口 代表,而不必顾虑它所在的类继承层次 ;这样可以最大限度地利用动态绑定,隐藏实现细节
实现不同类之间的常量 共享
接口允许我们在看起来不相干的对象之间定义共同行为,如下UML类图所示:
3、接口的语法
1 2 3 [接口修饰符] interface 接口名称 [extends 父接口名]{ }
注意:
接口的数据成员一定要有初值 ,且此值将不能再更改,可以省略final
关键字,即接口中每一个方法是隐式抽象 的,接口中的方法被隐式的指定为 public abstract
(只能是public abstract
,其他修饰符都会报错);
接口中的方法必须是抽象方法 ,不能有方法体,可以省略public
及abstract
关键字,即接口中的变量会被隐式的指定为public static final
变量(并且只能是public
,用private
修饰会报编译错误)。
4、接口与类的区别
接口不能用于实例化对象。
接口没有构造方法。
接口中所有的方法必须是抽象方法 ,只能由实现接口的类来实现接口中的方法。
接口不能包含成员变量,除了static
和final
变量。
接口不是被类继承了,而是要被类实现 。
接口支持多继承 。
5、抽象类和接口的区别
抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
注:JDK 1.8 以后,接口里可以有静态方法和方法体了。
抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final
类型的。
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
**强调:**接口有以下特性
接口是隐式抽象的,当声明一个接口的时候,不必使用abstract
关键字。
接口中每一个方法也是隐式抽象的,声明时同样不需要abstract
关键字。
接口中的方法都是公有的。
例:接口声明
声明一个接口Shape2D,包括π和计算面积的方法原型
1 2 3 4 interface Shape2D { final double pi = 3.14 ; public abstract double area () ; }
在接口的声明中,允许省略一些关键字,也可声明如下
1 2 3 4 interface Shape2D { double pi = 3.14 ; double area () ; }
6、实现接口
(1) 单一接口的实现
不能用new
运算符直接产生接口对象。
利用接口设计类的过程,称为接口的实现,使用implements
关键字,语法如下:
1 2 3 4 public class 类名称 implements 接口名称 { }
注意:
必须实现接口中的所有方法;
来自接口的方法必须声明成public
。
例:实现接口 Shape2D
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Circle implements Shape2D { double radius; public Circle (double r) { radius = r; } public double area () { return (pi * radius * radius); } } class Rectangle implements Shape2D { int length, width; public Rectangle (int l, int w) { length = l; width = w; } public double area () { return (width * length); } } public class InterfaceTester { public static void main (String args[]) { Rectangle rect = new Rectangle(5 , 6 ); System.out.println("Area of rect = " + rect.area()); Circle cir = new Circle(2.0 ) System.out.println("Area of cir = " + cir.area()); } }
运行结果:
1 2 Area of rect = 30.0 Area of cir = 12.56
(2) 多个接口的实现
Java不允许一个类有多个超类
一个类可以实现多个接口,通过这种机制可实现对设计的多重继承。
实现多个接口的语法如下:
1 2 3 4 [类修饰符] class 类名称 implements 接口1, 接口2, … { }
强调:
重写接口中声明的方法时,需要注意以下规则:
类在实现接口的方法时,不能抛出强制性异常 ,只能在接口中,或者继承接口的抽象类中 抛出该强制性异常。
类在重写方法时要保持一致的方法名 ,并且应该保持相同或者相兼容的返回值类型 。
如果实现接口的类是抽象类 ,那么就没必要实现该接口的方法 。
在实现接口的时候,也要注意一些规则:
一个类只能继承一个类 ,但是能实现多个接口 。
一个接口能继承另一个接口,这和类之间的继承比较相似。
7、接口类型的引用变量
接口的灵活性就在于“规定了一个类必须做什么,而不管你如何做”。
我们可以定义一个接口类型的引用变量 来引用实现接口的类的对象 ,当这个引用来调用方法时,它会根据实际引用的类的实例来判断具体调用哪个方法 (实现了方法在运行时的动态绑定)。
例:
1 2 3 4 5 6 7 8 9 public class VariableTester { public static void main (String args[]) { Shape2D var1, var2; var1 = new Rectangle(5 , 6 ); System.out.println("Area of var1 = " + var1.area()); var2 = new Circle(2.0 ); System.out.println("Area of var2 = " + var2.area()); } }
运行结果:
1 2 Area of rect = 30.0 Area of cir = 12.56
8、接口的扩展
接口可通过扩展的技术派生出新的接口
原来的接口称为超接口(super interface);
派生出的接口称为子接口(sub interface)。
一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends
关键字,子接口继承父接口的方法。
在Java中,类的多继承是不合法,但接口允许多继承。
在接口的多继承中extends
关键字只需要使用一次,在其后跟着继承接口。
接口扩展的语法:
1 2 3 interface 子接口的名称 extends 超口的名称1, 超接口的名称2, … { }
注意:实现一个接口的类也必须实现其超接口。
例:Shape 是超接口,Shape2D 与 Shape3D 是其子接口。Circle 类及 Rectangle 类实现接口 Shape2D, 而 Box 类及 Sphere 类实现接口 Shape3D。关系可由如下UML类图表示:
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 interface Shape { double pi = 3.14159 ; void setColor (String str) ; } interface Shape2D extends Shape { double area () ; } interface Shape3D extends Shape { double superficialArea () ; double volume () ; } class Circle implements Shape2D { double radius; String color; public Circle (double r) { radius = r; color = "white" ; System.out.println("New Circle: radius = " + radius); } public double area () { return (pi * radius * radius); } public void setColor (String str) { color = str; System.out.println("color = " + color); } } class Rectangle implements Shape2D { int length, width; String color; public Rectangle (int l, int w) { length = l; width = w; color = "white" ; System.out.println("New Rectangle: length = " + length + ", width = " + width); } public double area () { return (width * length); } public void setColor (String str) { color = str; System.out.println("color = " + color); } } class Box implements Shape3D { int length, width, height; String color; public Box (int l, int w, int h) { length = l; width = w; height = h; color = "white" ; System.out.println("New Rectangle: length = " + length + ", width = " + width + ", height = " + height); } public double superficialArea () { return (2 * length * width + 2 * height * width + 2 * length * height); } public double volume () { return (length * width * height); } public void setColor (String str) { color = str; System.out.println("color = " + color); } } class Sphere implements Shape3D { double radius; String color; public Sphere (double r) { radius = r; color = "white" ; System.out.println("New Sphere: radius = " + radius); } public double superficialArea () { return (4 * pi * radius * radius); } public double volume () { return (4 * pi * radius * radius * radius / 3 ); } public void setColor (String str) { color = str; System.out.println("color = " + color); } } public class ExtendsInterfaceTester { public static void main (String[] args) { Circle cir; cir = new Circle(2.0 ); cir.setColor("blue" ); System.out.println("Area of Circle cir is " + cir.area()); System.out.println(); Rectangle rec; rec = new Rectangle(5 , 6 ); rec.setColor("red" ); System.out.println("Area of Rectangle rec is " + rec.area()); System.out.println(); Box box; box = new Box(3 , 4 , 5 ); box.setColor("green" ); System.out.println("Superficial Area of Box box is " + box.superficialArea()); System.out.println("Volume of Box box is " + box.volume()); System.out.println(); Sphere sph; sph = new Sphere(15.0 ); sph.setColor("yellow" ); System.out.println("Superficial Area of Sphere sph is " + sph.superficialArea()); System.out.println("Volume of Sphere sph is " + sph.volume()); System.out.println(); } }
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 New Circle: radius = 2.0 color = blue Area of Circle cir is 12.56636 New Rectangle: length = 5, width = 6 color = red Area of Rectangle rec is 30.0 New Rectangle: length = 3, width = 4, height = 5 color = green Superficial Area of Box box is 94.0 Volume of Box box is 60.0 New Sphere: radius = 15.0 color = yellow Superficial Area of Sphere sph is 2827.431 Volume of Sphere sph is 14137.155
9、标记接口 △
最常用的继承接口是没有包含任何方法的接口。
标记接口 是没有任何方法和属性的接口。它仅仅表明它的类属于一个特定的类型 ,供其他代码来测试允许做一些事情。
标记接口作用 :使对象拥有某个或某些特权。(就是给某个对象打个标、盖个戳)
例如:java.awt.event
包中的MouseListener
接口继承的java.util.EventListener
接口定义如下:
1 2 package java.util;public interface EventListener {}
标记接口主要用于以下两种目的 :