接口的概念

java中的接口用于描述类应该具备什么样的功能,而不给出具体的实现,一个类可以“实现”多个接口
【注意】接口不是类,而是对类的一组描述
 
还是让我们通过一个例子来看看接口如何运作吧!
 
java文件结构:  
├─myInterface.java  
└─Myclass.java

myInterface.java :

public interface myInterface {
     int function ( int arg ) ;
}
Myclass.java:
public class Myclass implements myInterface{
  public int function(int arg) {
    ;
  }
}
在上面这个例子中,我们称 Myclass实现了(implements了)myInterface这个接口
 

接口的一些特性

 
1.置入一个接口的所有字段都自动具有static 和final 属性, 也就是说,所有的字段都是静态常量
2.字段和方法只能被public修饰, 而不能被private或者protected修饰(你可以不写出public,因为默认就是由public修饰的)
 
例如,如下用private修饰一个字段会导致报错
public interface myInterface {
    private int a;
}
报的错误是:
Illegal modifier for the interface field myInterface.a; only public, static & final are permitted

对比是学习的一种方式,下面我对接口的介绍,将在一系列的对比中展开

 

接口和超类的差异

 
我们发现,接口的定义方式和使用和超类很相似,例如:
超类的定义和使用:
public class superClass {  ... }
public class subClass extends superClass { ...}
接口的定义和使用:
public interface myInterface { ... }
public class Myclass implements myInterface{ ...}
 
就使用而言,超类通过class关键字定义, 并通过extends去“继承”,而接口通过interface关键字定义,并通过implement去“实现”
 
那么“接口”和“超类”有什么不同呢?
 

超类是一个“模板”,而接口是一种“契约”

 
超类的作用是为子类提供可复用(继承)的方法和域,并允许子类在此基础上添加新的方法和域,超类是一个“模板”
而接口实现却不一样,接口并不提供给子类能够使用的方法。相反,接口约定了一组方法,并强制要求implements了(也即实现了)这个接口的类去“实现”接口约定的方法,接口是一种“契约”
 
如果你在implements了接口的类中没有按要求“实现”接口约定的方法的话,是会导致报错的,例如:
 

报的错误是:
The type Myclass must implement the inherited abstract method myInterface.function(int)
我们通过提示的quick fix修复一下:

 
可以看到,“实现”了接口约定的这个function方法后,报错消失了, 那怎么才算符合约定呢?这要求对应的方法的返回值类型和参数类型都和接口里的相同
 
让我对接口和超类的作用打个比方:
 

超类继承

我们假设有这么一个年轻人(子类),如果他有一个有钱的老爸(超类),那么因为他可以直接从父亲(超类)获得这一部分财产:房子,车和钱(继承的方法),甚至于他可以不用工作,游手好闲(可以“拥有”超类提供的方法)。当然了,如果他还算是个有上进心的年轻人的话, 他也可以在已有基础上,自己打拼挣一些钱(属于子类自身的方法,或者覆盖超类原有的方法)
 

 

接口实现

 
但如果这个年轻人(类)生于一个相对普通的家庭,而且还有一个望子成龙的母亲(接口)的话,那么在他妈的严格要求下,他就必须靠自己的努力工作,去取得房子,车和钱(实现接口中约定的方法),并且他妈可能会要求他: 达不到目标就不要回来了! (如果没有实现接口约定的全部方法会报错)
 

 
代码如下:
 
超类继承
 
SuperClass.java:
public class SuperClass {
    public String  getMoney () {// 获取金钱
      return "Money"; 
    }
    public String getHouse () {  // 获取房子
      return  "house";
    }
    public String getCar () {   // 获取车子
      return "car";
    }
}
Myclass.java:
public class Myclass extends SuperClass{
  public String getAll () {
    return getMoney() + "   " + getCar() + "   "  + getHouse();
  }
  public static void main(String args []) {
    Myclass me = new Myclass();
     System.out.println(me.getAll());
  }
}
运行结果:
Money   car   house
 
接口实现:
 
myInterface.java:
public interface myInterface {
    public String  getMoney ();
    public String getHouse ();
    public String getCar ();
}

Myclass.java:

public class Myclass implements myInterface{
  public String  getMoney () { 
    return "Money";  
  }
  public String getHouse () { 
    return  "house";
  }
  public String getCar () {
    return "car";
  }
  
  public String getAll () {
    return getMoney() + "   " + getCar() + "   "  + getHouse();
  }
  public static void main(String args []) {
    Myclass me = new Myclass();
    System.out.println(me.getAll());
  }
}
 
运行结果:
Money   car   house
 

接口和抽象类的差异

 
接口和抽象类在使用形式上非常相似
AbstractClass.java:
abstract class AbstractClass {
   public abstract int function ();
}
MyClass.java:
public class MyClass extends AbstractClass {
  public int function() {
    ;
  }
}

接口和抽象类的共同点

1.都要求类(或子类)实现某一组约定的方法
2. 不能实例化
 

接口和抽象类的不同点

1.抽象类是归根结底还是类,它是对某一具体的类的抽象,而接口是对某一行为的抽象。
2.就抽象这一特性而言,抽象类关注的是整体,而接口关注的是局部。
3.抽象类约定的方法是从该抽象类的子类中提取出来的,而接口约定的方法是从许多不同的类中根据共通的部分提取出来的
 
我们上面提到,正因为“抽象类是归根结底还是类”,而接口不是类,所以:
1.抽象类可以有构造器,而接口不能有构造器
2.抽象类的抽象方法可以有public、protected,default修饰符,接口方法修饰符只能是public。
3.抽象类的抽象方法可以有main方法,接口不允许有main方法
 

接口实现/接口继承和类继承的差异

1.一个类可以实现多个接口
2. 一个接口可以继承另外一个接口,且允许“接口多继承”
 

一个类可以实现多个接口

 
为了避免多继承带来的复杂性,java舍弃了多继承的特性,也即一个类不能有多个超类:
// 没有这种写法,这是非法行为
public class MyClass extends SuperClass1,SuperClass2 {   }
但是一个类却允许实现多个接口,例如:
public class MyClass implements interface1, interface2 {  }
 
具体的例子:
我们有这样一个情景: 一个技术小白(例如我),每天要做的事情除了上学读书外,剩下的事件用来写技术文章
这个情景转化为代码是这样的: 有一个 TechXiaoBai类, 这个类要实现两个接口:Education和Blog,其中Education接口约定了study方法,而Blog接口约定了 Education接口
 
java文件结构:  

├─TechXiaoBai.java   // 主力类
├─Blog.java                // 接口1
└─Education.java       // 接口2 
TechXiaoBai.java
public class TechXiaoBai implements Blog, Education {
  // 作为一名技术小白每天要做的事情
  public void study() {  }
  public void writeArticle() {  }
}
Blog.java:
public interface Blog {
  void writeArticle (); // 写文章
}
 
Education.java:
public interface Education {
  void study(); // 学习
}
 
图示:
 
 

java允许“接口多继承”

 
java除了允许一个类继承多个接口外,还允许一个接口继承另外一个接口,甚至还允许“接口多继承”
 
具体的例子(紧接上面):
我们有这样一个情景: 在技术小白读书的过程中,具体又分为几个方面:本科生教育和研究生教育,假设这个技术小白想要读研的话——
 
那么这个情景转化为代码是这样的: 我们为上面提到的Education接口再提供两个扩展性的“父”接口:Undergraduate接口和Postgraduate接口
Undergraduate接口约定了learnBasicKowledge方法(学习基础知识),而Postgraduate接口约定了doScientificRearch方法(搞科研)
 
代码如下:
 
java文件结构:  

├─TechXiaoBai.java   // 主力类
├─Blog.java                // 接口1
├─Education.java        // 接口2
├─Undergraduate.java // 新增被Education接口继承的接口,接口2.1
└─Postgraduate.java    // 新增被Education接口继承的接口,接口2.2
Undergraduate.java:
// “本科生”接口
public interface Undergraduate {
   void learnBasicKowledge();  // 学习基础知识
}
Postgraduate.java:
// 研究生接口
public interface Postgraduate {
   void doScientificRearch(); // 搞一搞科研啦
}
Education.java:
public interface Education extends Undergraduate, Postgraduate{
  void study(); // 学习
}
 
TechXiaoBai.java:
public class TechXiaoBai implements Blog, Education {
  // 每天要做的事情
  public void study() {  }
  public void writeArticle() {  }
  public void learnBasicKowledge() {  }  // 新增方法
  public void doScientificRearch() {  }   // 新增方法
}
 
图示:
 

 
实际上:
public interface Education extends Undergraduate, Postgraduate{
  void study(); // 学习
}
相当于将Eduation接口变成了:
public interface Education extends Undergraduate, Postgraduate{
  void study(); // 学习
  void learnBasicKowledge();   // 学习基础知识
  void doScientificRearch(); // 搞一搞科研啦
}
 

接口存在的意义

 
了解接口的意义,让我们从一个例子开始,java中的Arrays类的Arrays.sort方法可以对对象类型的数组元素进行排序(Arrays.sort(Object [])),但是前提是对象所属的类必须实现了Comparable接口,而Comparable接口约定了compareTo方法。
 
Comparable接口的代码如下:
public interface Comparable<T>
{
  int compareTo(T other) // parameter has type T
}
Comparable接口对compareTo方法的实现的具体要求是:如果当前对象大于参数对象则返回正数,相反则返回负数,相等返回0
 
下面是一个示范例子:
有一个Student类,类中有实例变量score(分数), 我们创建一个Student类型的数组存放不同的Student对象并根据其score的大小进行从小到大的排序:

import java.util.Arrays;
 
public class Student implements Comparable<Student>{
    private int score; // 每个学生的分数
    public Student (int score) { 
      this.score = score;
    }
    public int getScore () { // 获取每个学生对象的分数
      return this.score;
    }
    @Override
    public int compareTo(Student other) { // 实现Comparable接口约定的compareTo方法
      return this.score - other.score;
    }
    public static void main (String [] args){
      Student [] stuArray = ]; // 声明Student类型的数组
      stuArray[] = );  // 将三个Student对象赋给数组
      stuArray[] = );
      stuArray[] = );
      stuArray[] = );
      Arrays.sort(stuArray);  // 进行从小到大的排序
      ; i<stuArray.length; i++){
        System.) +"个学生对象的分数:" +     stuArray[i].getScore());
      }
    }
}
运行结果:
排序后数组里第1个学生对象的分数:
排序后数组里第2个学生对象的分数:
排序后数组里第3个学生对象的分数:
排序后数组里第4个学生对象的分数:
 
接口声明了一个类应该实现哪些功能,但它又并不负责这些功能的具体实现,它告诉了我们这个类“用来做什么”,但是不告诉我们“具体怎么做”
 
1.它为各种不同的方法的实现提供了足够的自由度,例如用来为数组元素排序的ArrayList.sort方法,是没有办法指定一种特定的排序的方式的,让我们思考下,数组元素是“学生类的对象”和“老师类的对象”的时候排序的思路肯定不一样, 就算数组元素是某一特定的对象例如“学生对象”,根据需求的不同排序的方式也会有很大的不同:按照年龄来排序?按照成绩来排序?或者是按照姓氏的首字母排序?
指定一个没有固定实现的接口就可以为这种情况提供足够的自由度
 
2. 在ArrayList.sort中可能存在如下的语句:
){
   // 对a[i]和a[j]进行排序
}
因为Comparable接口要求实现这接口的类必须具有compareTo方法,所以在上面的例子中,通过接口,我们就可以确保a数组的数组元素一定是拥有compareTo方法,从而通过编译器的检查
 
 
【完】

【java】聊聊java里的接口的更多相关文章

  1. JVM:从实际案例聊聊Java应用的GC优化

    原文转载自美团从实际案例聊聊Java应用的GC优化,感谢原作者的贡献 当Java程序性能达不到既定目标,且其他优化手段都已经穷尽时,通常需要调整垃圾回收器来进一步提高性能,称为GC优化.但GC算法复杂 ...

  2. [JAVA设计模式]第一部分:接口、抽象类、设计原则

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  3. JAVA的免费天气api接口调用示例

    step1:选择本文所示例的接口"免费天气api" url:https://www.juhe.cn/docs/api/id/39/aid/87 step2:每个接口都需要传入一个参 ...

  4. Java字节码里的invoke操作&&编译时的静态绑定与动态绑定

    一个一直运行正常的应用突然无法运行了.在类库被更新之后,返回下面的错误. Exception in thread "main" java.lang.NoSuchMethodErro ...

  5. Java 8新特性之接口改善(八恶人-1)

    Daisy Donergue 多莫歌·黛西 “By woman, you mean her?” 她也能叫女人? Java 8在13年9月发布,写这篇博文的时间已经是17年12月份了.来的有点晚,但是有 ...

  6. Java程序设计8——抽象类、接口与内部类

    1 抽象类 当编写一个类时,常常会为该类定义一些方法,这些方法用以描述该类的行为方式,那么这些方法都有具体的方法体.但在某些情况下,某个父类并不需要实现,因为它只需要当做一个模板,而具体的实现,可以由 ...

  7. 聊聊Java并发面试问题之公平锁与非公平锁是啥?

    一.什么是非公平锁? 先来聊聊非公平锁是啥,现在大家先回过头来看下面这张图. 如上图,现在线程1加了锁,然后线程2尝试加锁,失败后进入了等待队列,处于阻塞中.然后线程1释放了锁,准备来唤醒线程2重新尝 ...

  8. Java集合框架之Map接口浅析

    Java集合框架之Map接口浅析 一.Map接口综述: 1.1java.util.Map<k, v>简介 位于java.util包下的Map接口,是Java集合框架的重要成员,它是和Col ...

  9. Java基础之抽象类与接口

    Java基础之抽象类与接口 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候 ...

随机推荐

  1. CentOS 7 服务器配置--配置Tomcat开机启动

    #编辑Tomcat的文件,追加内容 vi /data/tomcat/apache-tomcat-8.0.43/bin/catalina.sh #追加内容,在CLASSPATH= 上面的第三行 CATA ...

  2. html table中单元格自动换行

    table中单元格自动换行样式: table-layout: fixed; word-wrap: break-word;   table-layout 可能的值(IE不支持inherit属性) 值 描 ...

  3. js通过添加随机数的方法,解决多张图片加载时由于缓存导致图片无法正确显示的问题

    问题出现描述:当对列表中某个图片进行重新编辑时,提交后会发现图片列表仍会出现修改之前的图片,新图片并未覆盖. 问题出现原因:缓存问题. 解决办法:通过js方法,在每张图片路劲后面添加一个随机数,这样每 ...

  4. C#高级编程:泛型优点和特性

    泛型是CLR 2.0的一个新特性,在CLR 1.0中,要创建一个灵活的类或方法,但该类或方法在编译期间不知道使用什么类,就得以Object类为基础.而Object在编译期间没有类型安全性,因此必须进行 ...

  5. 【Linux】Apache Httpd 服务管理

    基本的操作方法: 本文假设你的apahce安装目录为/usr/local/apache2,这些方法适合任何情况 apahce启动命令: 推荐 [user@master1 ~]$  /usr/local ...

  6. 原型及原型链,以及prototype和__proto__属性(笔记便于以后复习)

    首先,js的数据结构有 原始类型(5种):Boolean.Number.String.Null.Underfined, 然后是引用类型:Array.Date.Error.RegExp.Function ...

  7. 查询session内容

    Enumeration enumsession = request.getSession().getAttributeNames(); while(enumsession.hasMoreElement ...

  8. Entity Framework Core 2.0 中使用LIKE 操作符

    Entity Framework Core 2.0 中使用LIKE 操作符 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译 ...

  9. 工具类:将其他编码类型转换成UTF-8或者其他类型的工具类

    将其他编码类型转换成UTF-8或者其他类型的工具类 public static String changeUTF(String str) { String newStr = null; try { n ...

  10. mysql:Linux系统下mysql5.6的安装卸载

    1.1. 下载rpm包 要使用yum 安装mysql,需要mysql的yum仓库,先从官网下载适合你系统的仓库 http://dev.mysql.com/downloads/repo/yum/ 我的是 ...