深入理解java中的接口 (Interface)

概念

我们知道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 修饰的

猜你喜欢

转载自blog.csdn.net/qq_40550018/article/details/84818794