概念
我们知道java中是单继承的,这就有了很多的限制,比如我们需要多继承的时候但是不能用多继承,这时候怎么办呢?就引入了接口的概念,它弥补了java中单继承的缺陷,这一点非常的好,如果要约定子类的实现要求并避免单继承局限就需要使用接口。
那么什么是接口呢?
接口就是抽象方法和全局常量的集合,使用Interface关键字。
定义
接口如何定义?它与类又有什么区别呢?
我们先来定义一个接口
例如:
Interface IMessage{
public static final String COUNTRY="China";//全局常量
public abstract void print();//抽象方法
}
上面这样的代码就是一个简单的接口的定义,我们为了区分接口,一般在接口名称前加上字母Interface的首字母I并且大写。
由于接口中的方法都是抽象方法和全局常量,我们一般可以省略抽象方法前面的修饰public abstract,以及常量前面public static final的修饰,例如:
Interface IMessage{
String COUNTRY="China";//全局常量
void print();//抽象方法
}
我们会发现接口里面并没有一些具体的信息,那么我们如何使用接口呢?
接口和抽象类一样,不能直接实例化,抽象类由继承它的子类实现它的抽象方法,那么接口也有自己的实现类,可以通过接口的实现类实现实例化。
对于它的实现类:
接口的实现类必须实现接口中的所有抽象方法,然后实现类可以通过向上转型为它的任意接口,然后实例化。
例如下面的代码:
interface IMessage{
public static final String MSG = "message" ; // 全局常量
public abstract void print() ; // 抽象方法
}
interface INews {
public abstract String getNews() ;
}
class MessageImpl implements IMessage,INews {
public void print() {
System.out.println(IMessage.MSG) ;
}
public String getNews(){
return IMessage.MSG ; // 访问常量都建议加上类名称
}
}
public class Test{
public static void main(String[] args) {
IMessage m = new MessageImpl() ; //子类向上转型,为父接口实例化对象
m.print() ; // 调用被子类覆写过的方法
INews n = (INews) m ;
System.out.println(n.getNews()) ;
}
}
我们看看上面这段代码的转换关系如下:
接口的使用限制
在上面的定义中我们知道了接口中,不论是属性还是方法,权限都是public的,那么这就决定了子类在实现接口时实现接口抽象方法的权限只能是public。
有些人实现的时候习惯和接口中一样权限什么都不写,这样是错误的,因为什么都不写默认的权限是default权限的,它的权限低于public,就会容易出错。
当一个子类既需要继承父类又需要实现接口时,应该先继承再实现
例如:
interface IMessage {
public void print() ;
}
abstract class News {
// 抽象类中方法前面的abstract不能省略,否则就是普通方法
public abstract void getNews() ;
}
class MessageImpl extends News implements IMessage {
public void print() {
System.out.println("I am a biter") ;
}
public void getNews() {
System.out.println("I am News") ;
}
}
需要注意的是:一个抽象类可以实现多个接口,但是接口不能继承类,接口可以继承接口
看一个抽象类实现接口的例子:
interface IMessage {
public void print() ;
}
abstract class News implements IMessage{
//News为抽象类,可以不实现IMessage中的抽象方法
// 抽象类中方法前面的abstract不能省略,否则就是普通方法
public abstract void getNews() ;
}
class MessageImpl extends News {
public void print() {
System.out.println("I am a biter") ;
}
public void getNews() {
System.out.println("I am News") ;
}
}
当然,在java中,一个接口可以继承多个父接口,例如:
interface A {
public void printA() ;
}
interface B {
public void printB() ;
}
interface C extends A,B { // 接口多继承
public void printC() ;
}
class Impl implements C{
public void printA() {}
public void printB() {}
public void printC() {}
}
public class Test{
public static void main(String[] args) {
}
}
总结
- 接口里定义抽象方法
- 接口里定义常量
- JDK7-11接口的一些变量(默认方法)
- 接口是无法实例化的,只能通过实现类
- 接口实现类可以向上转型成它实现的任意一个接口类型
- 在接口中定义的变量实际是常量,并且public static final 修饰的
- 接口中定义的方法是一个抽象方法,默认使用public abstract 修饰的