├─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) { return 0; } }
在上面这个例子中,我们称 Myclass实现了(implements了)myInterface这个接口
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去“实现” 那么“接口”和“超类”有什么不同呢?
报的错误是:
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
abstract class AbstractClass { public abstract int function (); }
MyClass.java:
public class MyClass extends AbstractClass { public int function() { return 0; } }
【吐槽】我去!这看起来不和接口一模一样吗?!
// 没有这种写法,这是非法行为 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(); // 学习 }
图示:
├─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(); // 搞一搞科研啦 }
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 = new Student[4]; // 声明Student类型的数组 stuArray[0] = new Student(100); // 将三个Student对象赋给数组 stuArray[1] = new Student(60); stuArray[2] = new Student(80); stuArray[3] = new Student(30); Arrays.sort(stuArray); // 进行从小到大的排序 for(int i =0; i<stuArray.length; i++){ System.out.println("排序后数组里第"+ (i+1) +"个学生对象的分数:" + stuArray[i].getScore()); } } }
运行结果:
排序后数组里第1个学生对象的分数:30 排序后数组里第2个学生对象的分数:60 排序后数组里第3个学生对象的分数:80 排序后数组里第4个学生对象的分数:100
接口声明了一个类应该实现哪些功能,但它又并不负责这些功能的具体实现,它告诉了我们这个类“用来做什么”,但是不告诉我们“具体怎么做” 1.它为各种不同的方法的实现提供了足够的自由度,例如用来为数组元素排序的ArrayList.sort方法,是没有办法指定一种特定的排序的方式的,让我们思考下,数组元素是“学生类的对象”和“老师类的对象”的时候排序的思路肯定不一样, 就算数组元素是某一特定的对象例如“学生对象”,根据需求的不同排序的方式也会有很大的不同:按照年龄来排序?按照成绩来排序?或者是按照姓氏的首字母排序? 指定一个没有固定实现的接口就可以为这种需求的具体实现提供足够的自由度 2. 在ArrayList.sort中可能存在如下的语句:
if(a[i].compareTo(a[j])>0){ // 对a[i]和a[j]进行排序 }
因为Comparable接口要求实现这接口的类必须具有compareTo方法,所以在上面的例子中,通过接口,我们就可以确保a数组的数组元素一定是拥有compareTo方法,从而通过编译器的检查 参考资料 《java核心技术 卷1》—— Cay S. Horstmann, Gary Cornell
【完】