规范与实现相分离的设计哲学
- 扩展功能
- 降低耦合
- 一个类可以继承一个父类,可以实现多个接口
- 接口是另一种定义数据类型的方式,它和类非常相似的。
- 接口中只包含常量,抽象方法
- 接口是另一种定义数据类型的方式,它和类非常相似的。
- 相同之处:有成员变量、成员方法、继
- 不同之处:接口中的属性:常量(final)、方法:抽象方法(特殊的抽象类)
- 定义接口:
[ public ] interface 接口名 [ extends 父接口1,父接口2,… ]{
[ public ][ static ][ final ] 数据类型 属性名 = 常量值;
[ public abstract ] 返回值类型 方法名([形参表]);
}
public :缺省时:包内可访问
接口支持多继承,多个父接口之间用逗号分隔
常量:可部分省略或全部省略,但一般都写出final。 int MAX_SIZE = 50; ==public static final int MAX_SIZE = 50;
抽象方法:接口的方法默认为public abstract,一般不写修饰符interface Figure { final double P1 = 3.14; abstract void area(); } class Circle implements Figure{ double radius; public Circle(double r){ radius=r; } public void area(){ System.out.println("圆的面积="+pi*radius*radius); } } class Rectangle implements Figure{ double width,height; public Rectangle(double w,double h){ width = w; height = h; } public void area(){ System.out.println("矩形的面积="+width*height); } } public class Test { public static void main(String[] args) { Circle c = new Circle(10.0); c.area(); Rectangle r = new Rectangle(10.0,5.0) r.area(); } }
-
实现接口
接口定义后不能直接创建对象,必须由类实现接口后创建类的对象。
[public] class 类名 extends 基类 implements 接口1,…{
//类体
}
注意:接口中的方法都是抽象的,因此实现接口的类必须重写这些方法。
public class Circle implements Figure{
double radius;
public Circle(double r){
radius=r;
}
public void area(){
System.out.println("圆的面积="+pi*radius*radius);
}
}
注意:
方法头必须和接口定义中的方法头完全相同,public修饰符不能省略。
如果类实现了多个接口,必须重写这些接口中的所有方法。
接口不是类,不能使用new实例化接口,但可以声明接口变量。接口变量可以指向一个实现了该接口的类的对象。
Shape s=new Shape(); //错 Shape s=new Circle(); //对
可以使用instanceof来判断对象是否实现了某个接口。
虽然可以使用接口变量来引用实现接口类的对象,但这种引用只能引用接口的成员,否则会发生编译错误。interface Output { final int MAX_CACHE_LINE = 10; void out(); void getData(String msg); } interface Product { int getProduceTime(); } 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; } } public int getProduceTime(){ return 45; } public static void main(String[] args){ Output o = new Printer(); o.getData("轻量级"); o.getData("Stu"); o.out(); o.getData("基于"); o.getData("Ruby"); o.out(); Product p = new Printer(); System.out.println(p.getProduceTime()); Object obj = p; } } 强调:接口最适合为不相关的类提供通用功能,利用接口提供的方法,程序可以多态地处理这些完全不同的类的对象。
-
接口的继承
[public] interface 子接口 extends 父接口1,父接口2,…{
//静态属性;
//抽象方法;
}interface iA { int PROP_A = 5; void testA(); } interface iB { int PROP_B = 6; void testB(); } interface iC extends iA,iB { int PROP_C = 7; void testC(); }
-
接口和抽象类
-
相同
-
接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。
-
接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
-
-
区别
-
设计目的不同
-
接口:一种规范,类似于整个系统的“总纲”,制定了系统各模块应该遵循的标准。因此一个系统中的接口不应该经常改变
-
抽象类:多个子类的共同父类,体现的是模板式设计。可被当成系统实现过程中的中间产品,这个中间产品已经实现了部分功能,但这个产品还不能当成最终产品,必须更进一步的完善,这种完善可能有几种不同方式。
-
-
用法不同
-
(1)接口里只能包含抽象方法,抽象类可以包含普通方法。
-
(2)接口里不能定义静态方法,抽象类可以定义静态方法
-
(3)接口里只能定义静态常量属性,抽象类既包含普通属性、静态常量属性
-
(4)接口不包含构造方法,抽象类里构造方法不用于创建对象,是让子类调用
-
(5)接口里不能包含初始化块,抽象类可以包含初始化块
-
(6)一个类可以实现多个接口,一个只能继承一个父类
-
-
-