赞
踩
Java基础——接口
官方解释:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
我的解释:接口可以理解为一种特殊的类,里面全部是由全局常量和公共的抽象方法所组成。接口是解决Java无法使用多继承的一种手段,但是接口在实际中更多的作用是制定标准的。或者我们可以直接把接口理解为100%的抽象类,既接口中的方法必须全部是抽象方法。(JDK1.8之前可以这样理解)
就像一个类一样,一个接口也能够拥有方法和属性,但是在接口中声明的方法默认是抽象的。(即只有方法标识符,而没有方法体)。
1.用 interface 来定义。
2.java中,接口和类是并列的两个结构。
3. 抽象类和接口是两个并列的结构,抽象类也属于类的结构
jdk7以前:只能定义全局常量和抽象方法:
3.在 Java 接口中声明的变量其实都是常量(全局变量),接口中的变量声明,将隐式地声明为public static final 变量(并且只能是 public,用 private 修饰会报编译错误),即常量,所以接口中定义的变量必须初始化。可以省略 public、static 和 final。
4.接口中的所有方法都默认是由public abstract修饰的(抽象方法),只能是 public abstract,其他修饰符都会报错。可以省略public和abstract。
jdk8: 除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法。
5.接口中不能定义构造方法。构造方法用于创建对象,意味着接口不可以实例化。
6.如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化,如果实现类没有覆盖接口中的所有抽象方法,则此实现类仍为一个抽象类。
7.多个无关的类可以实现同一个接口
8.一个类可以实现多个无关的接口,弥补了java单继承的局限性,格式:class A extends B implements C,D,E{}
9.接口与接口之间可以继承(使用extends关键字),而且可以多继承。
10.接口的具体使用,体现多态性。
11.接口实际上可以看做是一种规范。
1.接口被用来描述一种抽象。
2.因为Java不像C++一样支持多继承,所以Java可以通过实现接口来弥补这个局限。
3.接口也被用来实现解耦。
4.接口被用来实现抽象,而抽象类也被用来实现抽象,为什么一定要用接口呢?接口和抽象类之间又有什么区别呢?原因是抽象类内部可能包含非final的变量,但是在接口中存在的变量一定是final,public,static的。
格式如下:
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明全局变量:可以使用省略写法
// 抽象抽象方法:可以使用省略写法
}
如:
package com.fan.domain2; public interface A { //全局常量,可以单独省略其中任何一个关键字 public static final double PI = 3.14; int a = 1; static int b = 2; final int c = 3; public final int d = 4; //等等 //省略了public abstract ,但是默认是有的,只是隐藏了,也可以单独省略其中一个 void eat();//抽象方法 public void sleep(); abstract void run(); }
接口有以下特性:
一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。
// 文件名: Sports.java public interface Sports { public void setHomeTeam(String name); public void setVisitingTeam(String name); } // 文件名: Football.java public interface Football extends Sports { public void homeTeamScored(int points); public void visitingTeamScored(int points); public void endOfQuarter(int quarter); } // 文件名: Hockey.java public interface Hockey extends Sports { public void homeGoalScored(); public void visitingGoalScored(); public void endOfPeriod(int period); public void overtimePeriod(int ot); }
Hockey接口自己声明了四个方法,从Sports接口继承了两个方法,这样,实现Hockey接口的类需要实现六个方法。
相似的,实现Football接口的类需要实现五个方法,其中两个来自于Sports接口。
在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口。 如下所示:Sports, Event都是接口
public interface Hockey extends Sports, Event{}
代码
package com.fan.domain2; import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; //体现接口的多态性 public class USBTest { public static void main(String[] args) { Computer computer = new Computer(); //1.创建了接口的非匿名实现类的非匿名对象 Flash flash = new Flash(); computer.transferData(flash); //2.创建了接口的非匿名实现类的匿名对象 computer.transferData(new Printer()); //3.创建了接口的匿名实现类的非匿名对象 USB phone = new USB() { public void start() { System.out.println("手机开始工作"); } public void stop() { System.out.println("手机工作结束"); } }; computer.transferData(phone); //4.创建了接口的匿名实现类的匿名对象 computer.transferData(new USB() { public void start() { System.out.println("mp3开始工作"); } public void stop() { System.out.println("mp3结束工作"); } }); } } interface USB { //常量:定义了长,宽,最大最小的传输速度等。 void start(); void stop(); } //电脑类 class Computer { //参数传递最能体现多态,这里体现接口的多态性 public void transferData(USB usb){//USB usb = new Flash() usb.start(); System.out.println("具体传输数据的细节"); usb.stop(); } } //优盘类 class Flash implements USB{ public void start() { System.out.println("u盘开启工作"); } public void stop() { System.out.println("u盘结束工作"); } } //打印机类 class Printer implements USB { public void start() { System.out.println("打印机开启工作"); } public void stop() { System.out.println("打印机结束工作"); } }
jdk8:除了定义全局常量和抽象方法外,还可以定义静态方法、默认方法
知识点1:接口中定义的静态方法,只能通过当前接口自己去调用。(即自己设置自己用)
知识点2:通过实现类的对象,可以调用接口中的默认方法。 如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写后的方法,和继承中的重写一样的.
知识点3:如果子类(或实现类)继承的父类和实现的接口(父接口)中声明了同名同参数的默认方法,那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。–>类优先原则,针对方法来的,属性不存在谁优先。
知识点4:如果实现类 仅仅是 实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的情况下,报错 —>接口冲突。
这时候就需要我们必须在实现类中重写此方法。
代码演示:
package com.fan.domain3; /* *jdk8:除了定义全局常量和抽象方法外,还可以定义静态方法、默认方法 */ public interface JDK8Test { public static void main(String[] args) { SubClass subClass = new SubClass(); //subClass.method1();子类完全看不到父接口的静态方法 //SubClass.method1(); //知识点1:接口中定义的静态方法,只能通过当前接口自己去调用。(即自己设置自己用) JDKFather.method1(); /*知识点2:通过实现类的对象,可以调用接口中的默认方法。 如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写后的方法,和继承中的重写一样的*/ subClass.method2(); /* *知识点3:如果子类(或实现类)继承的父类和实现的接口(父接口)中 * 声明了同名同参数的默认方法,那么子类在没有重写此方法的情况下,默认 * 调用的是父类中的同名同参数的方法。-->类优先原则,针对方法来的,属性不存在谁优先。 * * 知识点4:如果实现类 仅仅是 实现了多个接口,而这多个接口中定义了同名同参数的默认方法, * 那么在实现类没有重写此方法的情况下,报错 --->接口冲突。 * 这时候就需要我们必须在实现类中重写此方法。 * */ subClass.method3(); //SubClass.method2();//此方法是默认方法。 } } interface JDKFather{ //静态方法 public static void method1(){ System.out.println("父接口:北京1"); } //默认方法 public default void method2(){ System.out.println("父接口:上海2"); } default void method3(){ System.out.println("父接口:上海3"); } } //演示接口冲突,此时类去掉extends SuperClass关键字 interface JDKFather2{ default void method3(){ System.out.println("JDKFather2:上海3"); } } class SuperClass { public void method3(){ System.out.println("SuperClass:北京"); } } class SubClass extends SuperClass implements JDKFather,JDKFather2 { public void method2(){ System.out.println("子类:上海2"); } //演示接口冲突,此时类去掉extends SuperClass关键字 和去掉此方法演示 //如果加上此方法相当于重写了,调用的是子类重写后的方法 public void method3(){ System.out.println("子类:深圳"); } //知识点5:如何在子类(或实现类)的方法中调用父类、接口中的被重写的方法 public void myMethod(){ method3();//调用自己定义的重写的方法 super.method3();//调用的是父类中声明的 //调用接口中的默认方法 JDKFather.super.method3(); JDKFather2.super.method3(); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。