接口基本定义

接口基本定义

抽象类与普通类的最大优势在于:可以实现对子类覆写方法的控制,但是在抽象类中依然保留有一些普通方法,而普通方法中可能会涉及到一些安全或隐私的问题。在进行开发的过程中,如果想要对外部隐藏全部的实现细节,就可以通过接口来描述。

接口可以理解为一个纯粹的抽象类(最原始的定义接口中只包含抽象方法与全局变量),从JDK1.8开始由于引入了Lambda表达式的概念,所以接口的定义也得到了加强,除了抽象方法与全局变量外,还可以定义普通方法或静态方法。

从设计本身的角度来将,接口中的组成还是应该以抽象方法和全局变量为主。

在Java中接口主要食用interface关键字来进行定义。

对于接口需要注意以下几点:

1、接口需要被子类实现(implements),一个子类可以实现多个父接口;

2、子类(如果不是抽象类)那么一定要覆写接口之中的全部抽象方法;

3、接口对象可以利用子类对象的向上转型

范例:定义接口

package 面向对象;

//由于类名称与接口名称的定义要求相同,所以为了区分出接口,接口名称前往往会加入I
interface IMessage{  //定义了一个接口
    public static final String INFO = "www.mldn.cn";  //全局常量
    public abstract String getInfo(); //抽象方法
}

class MessageImpl implements IMessage { //实现了接口
    public String getInfo() {
        return "得到一个消息,秘密的消息,有人胖了(不是我)。";
    }
}

public class InterfaceDemo00 {
    public static void main(String[] args) {
        IMessage msg = new MessageImpl();  //向上转型
        System.out.println(msg.getInfo());  //子类对象msg调用其getInfo()方法
        System.out.println(IMessage.INFO);  //类名调用静态属性
    }
}

输出结果:
得到一个消息,秘密的消息,有人胖了(不是我)。
www.mldn.cn

关于接口的重要说明:

在Java中之所以使用接口的主要目的是一个子类可以实现多个接口,利用接口可以实现多继承的概念。

范例:观察子类实现多个父接口

package 面向对象;

//由于类名称与接口名称的定义要求相同,所以为了区分出接口,接口名称前往往会加入I
interface IMessage{  //定义了一个接口
    public static final String INFO = "www.mldn.cn";  //全局常量
    public abstract String getInfo(); //抽象方法
}

interface IChannel {
    public abstract boolean connect(); //定义抽象方法
}

class MessageImpl implements IMessage, IChannel { //实现了接口
    public String getInfo() {
        if (this.connect()) {
            return "得到一个消息,秘密的消息,有人胖了(不是我)。";
        }
        return "通道创建失败,无法获取消息。 ";
    }

    public boolean connect() {
        System.out.println("消息发送通道已经成功建立。");
        return true;
    }
}



public class InterfaceDemo00 {
    public static void main(String[] args) {
        IMessage msg = new MessageImpl();  //向上转型
        System.out.println(msg.getInfo());  //子类对象msg调用其getInfo()方法
        System.out.println(IMessage.INFO);  //类名调用静态属性
    }
}

输出结果:

消息发送通道已经成功建立。
得到一个消息,秘密的消息,有人胖了(不是我)。
www.mldn.cn

但是这时就需要考虑一个实际的情况了,考虑转型问题

package 面向对象;


//由于类名称与接口名称的定义要求相同,所以为了区分出接口,接口名称前往往会加入I
interface IMessage{  //定义了一个接口
    public static final String INFO = "www.mldn.cn";  //全局常量
    public abstract String getInfo(); //抽象方法
}

interface IChannel {
    public abstract boolean connect(); //定义抽象方法
}

class MessageImpl implements IMessage, IChannel { //实现了接口
    public String getInfo() {
        if (this.connect()) {
            return "得到一个消息,秘密的消息,有人胖了(不是我)。";
        }
        return "通道创建失败,无法获取消息。 ";
    }

    public boolean connect() {
        System.out.println("消息发送通道已经成功建立。");
        return true;
    }
}

public class InterfaceDemo00 {
    public static void main(String[] args) {
        IMessage msg = new MessageImpl();  //向上转型
        IChannel chl = (IChannel)msg;
        System.out.println(chl.connect());  //子类对象msg调用其getInfo()方法
    }
}

消息发送通道已经成功建立。
true

由于MessageImpl子类实现了IMessage和IChannel两个接口,所以这个子类可以是这两个接口中任意一个接口的实例,从而表示此时这两个接口实例之间是可以转换的。

在Java程序中接口是不能继承父类的。所以接口绝对不会是Object的子类,但是根据之前的分析可以发现,MessageImpl是Object的子类,所以接口一定可以通过Object接收。

范例:接口与Object类有关系吗

package 面向对象;

import javax.swing.*;

//由于类名称与接口名称的定义要求相同,所以为了区分出接口,接口名称前往往会加入I
interface IMessage{  //定义了一个接口
    public static final String INFO = "www.mldn.cn";  //全局常量
    public abstract String getInfo(); //抽象方法
}

interface IChannel {
    public abstract boolean connect(); //定义抽象方法
}

class MessageImpl implements IMessage, IChannel { //实现了接口
    public String getInfo() {
        if (this.connect()) {
            return "得到一个消息,秘密的消息,有人胖了(不是我)。";
        }
        return "通道创建失败,无法获取消息。 ";
    }

    public boolean connect() {
        System.out.println("消息发送通道已经成功建立。");
        return true;
    }
}

public class InterfaceDemo00 {
    public static void main(String[] args) {
        IMessage msg = new MessageImpl();  //向上转型
        Object obj = msg;  //向上转型
        IChannel chl = (IChannel)obj;  //向下转型
        System.out.println(chl.connect());  //子类对象msg调用其getInfo()方法
    }
}

输出结果:

消息发送通道已经成功建立。
true

Object类可以接收所有的数据类型,包括基本数据类型、类对象、接口对象、数组。

由于接口描述的是一个公共的定义标准,所以在

接口中所有的抽象方法的访问权限都是public,也即是写或者不写都是一样的

范例:下面的两个接口本质上是完全相同的


image.png

方法不写访问权限也是public,不是default,所以覆写的时候只能使用public;

接口虽然已经可以成功的进行了定义。但是在实际开发中,实现接口的可能是抽象类,一个抽象类可以实现多个接口,而一个普通类只能继承一个抽象类,并且可以实现,但是要求先继承后实现。

范例:子类先继承后实现

package 面向对象;

import javax.swing.*;

//由于类名称与接口名称的定义要求相同,所以为了区分出接口,接口名称前往往会加入I
interface IMessage{  //定义了一个接口
    public static final String INFO = "www.mldn.cn";  //全局常量
    public abstract String getInfo(); //抽象方法
}

interface IChannel {
    //接口中可以省略abstract属性
    public  boolean connect(); //定义抽象方法
}

abstract class DatabaseAbstract {  //定义一个抽象类
    //接口中的abstract可以省略,而抽象类中不可以省略
    //抽象类中不可以省略abstract属性
    public abstract boolean getDatabaseConnection();

}

class MessageImpl extends DatabaseAbstract implements IMessage, IChannel { //实现了接口

    @Override
    public boolean getDatabaseConnection() {
        return true;
    }
    public String getInfo() {
        if (this.connect()) {
            if (this.getDatabaseConnection()) {
                return "数据库中得到一个消息,秘密的消息,有人胖了(不是我)。";

            }else {
                return "数据库消息无法访问";
            }
        }
        return "通道创建失败,无法获取消息。 ";
    }

    public boolean connect() {
        System.out.println("消息发送通道已经成功建立。");
        return true;
    }
}

public class InterfaceDemo00 {
    public static void main(String[] args) {
        IMessage msg = new MessageImpl();  //向上转型
        System.out.println(msg.getInfo());
    }
}

输出结果:

消息发送通道已经成功建立。
数据库中得到一个消息,秘密的消息,有人胖了(不是我)。

虽然接口无法继承一个父类,但是一个接口却可以通过extends实现若干个父接口,此时称为接口的多继承。

范例:实现接口多继承

package 面向对象;

interface IMessage01 {
    public abstract String getInfo();
}

interface IChannel01 {
    public boolean connect();
}

//extends在类继承上只能继承一个父类,但是接口上可以继承多个
interface IService extends IMessage01, IChannel01 {
    public String service();
}
class MessageSevice implements IService {
    public String getInfo() {
        return null;
    }

    public boolean connect() {
        return true;
    }

    public String service() {
        return "获取消息服务。";
    }
}

public class InterfaceDemo01 {
    public static void main(String[] args) {

    }
}

在实际的开发中,接口的使用往往有三种形式:

进行标准设置
表示一种操作的能力
暴露远程方法视图,这个一般都是在RPC分布式开发中使用

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 1,262评论 0 2
  • 面向对象主要针对面向过程。 面向过程的基本单元是函数。 什么是对象:EVERYTHING IS OBJECT(万物...
    sinpi阅读 1,088评论 0 4
  • 本文出自 Eddy Wiki ,转载请注明出处:http://eddy.wiki/interview-java.h...
    eddy_wiki阅读 1,225评论 0 5
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,687评论 0 11
  • 面向对象编程(OOP) 在前面的章节中,我们学习了Kotlin的语言基础知识、类型系统、集合类以及泛型相关的知识。...
    Tenderness4阅读 4,479评论 1 6