接口
目录
接口的概念
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口的声明:
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
/* 文件名 : NameOfInterface.java */
import java.lang.*;
//引入包
public interface NameOfInterface
{
//任何类型 final, static 字段
//抽象方法
}
接口的实现:
...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...
/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
接口的特性
- 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
接口的好处
重要性:在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力。
简单、规范性:如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口不仅告诉开发人员你需要实现那些业务,而且也将命名规范限制住了(防止一些开发人员随便命名导致别的程序员无法看明白)。
维护、拓展性:比如你要做一个画板程序,其中里面有一个面板类,主要负责绘画功能,然后你就这样定义了这个类。
可是在不久将来,你突然发现这个类满足不了你了,然后你又要重新设计这个类,更糟糕是你可能要放弃这个类,那么其他地方可能有引用他,这样修改起来很麻烦。
如果你一开始定义一个接口,把绘制功能放在接口里,然后定义类时实现这个接口,然后你只要用这个接口去引用实现它的类就行了,以后要换的话只不过是引用另一个类而已,这样就达到维护、拓展的方便性。
安全、严密性:接口是实现软件松耦合的重要手段,它描叙了系统对外的所有服务,而不涉及任何具体的实现细节。这样就比较安全、严密一些(一般软件服务商考虑的比较多)。
接口和多态的关系
- 实现多态的一种方式:接口是实现多态性的一种重要方式。通过定义一个接口,并让不同的类实现这个接口,我们可以在运行时通过接口的引用变量来引用实现了该接口的任何类的对象。这样,我们就可以通过同一个接口引用变量来调用不同实现类中的方法,从而实现了多态性。
- 提高程序的扩展性和灵活性:接口定义了对象的行为规范,而具体的实现则留给各个类来完成。这种设计方式使得我们可以在不修改现有代码的基础上,通过添加新的实现类来扩展程序的功能,从而提高了程序的扩展性和灵活性。同时,这也体现了多态性的一个核心思想:即“可替换性”,即可以在不改变程序其他部分的情况下,用新的类替换现有的类。
- 解耦:接口和多态性的结合使用有助于实现软件设计中的一个重要原则——解耦。通过接口定义类之间的通信协议,我们可以降低类之间的耦合度,使得各个类可以独立地进行开发和测试。同时,这也使得系统更加易于维护和扩展。
- 实现动态绑定:在面向对象的语言中,接口和多态性通常与动态绑定(也称为晚期绑定或运行时绑定)一起使用。这意味着,程序在运行时才会确定具体调用哪个类的方法,而不是在编译时。这种机制为程序提供了更大的灵活性,因为它允许我们在运行时根据程序的状态或输入来决定使用哪个实现。