接口
接口与抽象类不同,它是一种规范,犹如USB、PCI接口规范一样。
接口与抽象类一样都不能创建实例,必须由接口的实现类完成对象的创建工作。
接口与抽象类的区别如下:
- 接口的数据成员必须是静态常量;抽象类可以有非常量的数据成员。
- 抽象类在体现父子继承关系时,是“is-a”的关系,即父类与子类在本质上是应该 相同的;接口不要求实现类是本质上的相同,而是按照接口的规定实现契约,是 “like-a”的关系,一般而言接口很多用于系统对外部的扩展。
- 继承特性也不太一样:一个类只能实现一个抽象类,但可以实现多个接口。
接口的定义
语法格式如下:
[public] interface 接口名称 [extends 父接口列表]{
[public] [static] [final] 数据类型 常量名=常量; //定义常量
[public] [abstract] 返回值类型 方法名称([参数列表]); //定义抽象方法
[public] static 返回值类型 方法名称([参数列表]){ //定义静态方法
… …
}
[public] default 返回值类型 方法名称([参数列表]){ //定义默认方法
… …
}
}
五个关键点:
- 数据成员是静态的,必须赋初值的,是作为一个常量的;
- 数据成员默认为 public static final;
- 抽象方法默认为 public abstract;
- 静态方法的修饰符static不能省略,默认方法的修饰符default不能省略;
- 接口中的成员都是public的。
接口的实现与引用
与抽象类一样,接口不能用于创建对象;要想创建接口的对象,必须使用接口的实现类。
语法如下:
class 类名称 implements 接口列表{
… …
}
五点说明:
- 如果实现接口的类不是抽象类,则该(实现)类必须实现接口中所有的抽象方法;
- 实现类在实现接口的抽象方法时,方法头必须与接口的方法头完全相同,否则就是 在定义一个新方法;
- 接口中的抽象方法都显式的或隐式的定义为public,在类的实现方法前必须显式的 使用public修饰符,否则系统将警告缩小了该方法的访问权限;
- 每个接口在编译时都会生成一个.class字节码文件;
- 接口类型是引用类型。
举例:
package ch08;
interface IShape{ //编译完成后会产生一个名为Ishape.class文件
final double PI=3.14;
abstract double getArea();
abstract double getLength();
}
class Circle implements IShape{ //编译完成后会产生一个名为 Circle.class文件
double radius;
public Circle(double r){
radius=r;
}
public double getArea(){
return PI*radius*radius;
}
public double getLength(){
return 2*PI*radius;
}
}
class Rectangle implements IShape{ //编译完成后会产生一个名为 Rectangle.class文件
private double width;
private double height;
public Rectangle(double width,double height){
this.width=width;
this.height=height;
}
public double getArea(){
return width*height;
}
public double getLength(){
return 2*(width+height);
}
}
public class Demo{ //编译完成后会产生一个名为 Demo.class文件
public static void main(String[] args){
IShape circle=new Circle(5.0); //用接口的实现类创建接口对象
System.out.println("PI="+IShape.PI); //接口的静态常量直接用接口调用
System.out.print("圆面积="+circle.getArea());
System.out.println(";周长="+circle.getLength());
Rectangle rect =new Rectangle(6.5,10.8);
System.out.print("矩形面积="+rect.getArea());
System.out.println(";周长="+rect.getLength());
}
}