java之接口

0x01.接口

什麼是接口?
接口是Java語言中的一種引用類型,是方法的"集合",因此接口的內部主要就是定義方法,包含常量,抽象方法(JDK 7及之前),默認方法和靜態方法(JDK 8),私有方法(jdk9)

接口的定義,它與定義類方式類似,可是使用 interface 關鍵字。它也會被編譯成.class文件,但必定要明確它並非類,而是另一種引用數據類型。java

public class 類名.java-->.class
public interface 接口名.java-->.class數組

引用數據類型:數組,類,接口。ide

接口的使用,它不能建立對象,可是能夠被實現( implements ,相似於被繼承)。一個實現接口的類(能夠看作是接口的子類),須要實現接口中全部的抽象方法,建立該類對象,就能夠調用方法了,不然它必須是一個抽象類。測試

實例:code

public interface IA {
    // 常量 默認修飾符是 public static final 這3個修飾符能夠省略不寫
    public static final int NUM = 10;
    int NUM1 = 20;

    // 抽象方法 默認修飾符是 public abstract 這2個修飾符能夠省略不寫
    public abstract void method1();
    void method2();

    // 默認方法 默認修飾符是 public default public能夠省略,default不能夠省略
    public default void method3(){
        System.out.println("IA 接口默認方法");
    }

    // 靜態方法 默認修飾符 public static public能夠省略,static不能夠省略
    public static void method4(){
        System.out.println("靜態方法");
    }

    // 私有方法 修飾符 private   private不能夠省略
    private void method5(){
        System.out.println("私有非靜態方法");
    }

    private static void method6(){
        System.out.println("私有靜態方法");
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            接口的定義:
                public interface 接口名{
                     jdk7及其之前:  常量,抽象方法
                     jdk8: 額外增長默認方法和靜態方法
                     jdk9及其以上: 額外增長了私有方法
                }
         */
        System.out.println(IA.NUM1);// 10
    }

    // 類中的默認方法,使用默認權限修飾符(空)
    void method(){

    }
}

實現概述

類與接口的關係爲實現關係,即類實現接口,該類能夠稱爲接口的實現類,也能夠稱爲接口的子類。實現的動做相似繼承,格式相仿,只是關鍵字不一樣,實現使用 implements關鍵字。對象

實現格式
  • 類能夠實現一個接口,也能夠同時實現多個接口。繼承

  • 類實現接口後,必須重寫接口中全部的抽象方法,不然該類必須是一個「抽象類」。接口

public interface IA{
    public void show1();
}
public interface IB{
    public void show2();
}
public class Zi implements IA ,IB{
    public void show1(){
    }
    public void show2(){
    }
}
  • 類能夠在「繼承一個類」的同時,實現一個、多個接口;
public class Fu{}
public interface IA{}
public interface IB{}
public class Zi extends Fu implements IA,IB{//必定要先繼承,後實現
}

接口中成員訪問特色概述

接口中成員的訪問特色:
                接口中的常量: 主要是供接口直接使用
                接口中的抽象方法: 供實現類重寫的
                接口中的默認方法: 供實現類繼承的(實現類中能夠直接調用,實現類對象也能夠直接調用)
                接口中的靜態方法: 只供接口直接調用,實現類繼承不了
                接口中的私有方法: 只能在接口中直接調用,實現類繼承不了
案例演示
/*
接口
*/
public interface IA {
    //  接口中的常量: 主要是供接口直接使用
    public static final int NUM = 10;

    // 接口中的抽象方法: 供實現類重寫的
    public abstract void method1();

    // 接口中的默認方法: 供實現類繼承使用(實現類中能夠直接調用,實現類對象也能夠直接調用)
    public default void method2(){
        System.out.println("默認方法method2");
        method4();
        method5();
    }

    // 接口中的靜態方法: 只供接口直接調用,實現類繼承不了
    public static void method3(){
        System.out.println("靜態方法method3");
        method5();
    }

    // 接口中的私有方法: 只能在接口中直接調用,實現類繼承不了
    private void method4(){// 只能在接口的默認方法中調用
        // 方法體
        method5();
    }

    private static void method5(){//
        // 方法體
    }
}

實現類:編譯

public class ImpA implements IA{

   /* @Override
    public void method2() {

    }*/

    @Override
    public void method1() {
        System.out.println("重寫接口中的method1抽象方法");
    }
}

測試類:class

public class Test {
    public static void main(String[] args) {
        /*
            接口中成員的訪問特色:
                接口中的常量: 主要是供接口直接使用
                接口中的抽象方法: 供實現類重寫的
                接口中的默認方法: 供實現類繼承的(實現類中能夠直接調用,實現類對象也能夠直接調用)
                接口中的靜態方法: 只供接口直接調用,實現類繼承不了
                接口中的私有方法: 只能在接口中直接調用,實現類繼承不了
         */
        System.out.println(IA.NUM);// 10

        // 建立實現類對象,訪問NUM常量
        ImpA ia = new ImpA();
        System.out.println(ia.NUM);// 10

        // 調用method2方法
        ia.method2();

        // 經過接口名調用接口中的靜態方法
        IA.method3();
        //ia.method3();// 編譯報錯,
    }
}

接口和接口的關係

  • 公有靜態常量的衝突
  • 公有抽象方法的衝突
  • 公有默認方法的衝突
  • 公有靜態方法的衝突
  • 私有方法的衝突

講解

公有靜態常量的衝突
  • 實現類不繼承衝突的變量
interface IA{
    public static final int a = 10;
    public static final int b= 20;
}
interface IB{
    public static final int a = 30;
}
class Zi implements IA,IB{
    //只繼承了b,沒有繼承a,由於a衝突了
}

public class Demo {
    public static void main(String[] args) {
        Zi z = new Zi();
     //   System.out.println(z.a);//編譯錯誤
        System.out.println(z.b);
    }
}
公有抽象方法的衝突
  • 實現類只須要重寫一個
interface IA{
    public void show();
}
interface IB{
    public void show();
}
class Zi implements IA,IB{
    @Override
    public void show() {//子類只須要重寫一個show()便可
        System.out.println("子類的show()...");
    }
}
public class Demo {
    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();
    }
}
公有默認方法的衝突
  • 實現類必須重寫一次最終版本
interface IA{
    public default void show(){
        System.out.println("IA");
    }
}
interface IB{
    public default void show(){
        System.out.println("IB");
    }
}
class Zi implements IA,IB{
    @Override
    public void show() {//必須重寫一次的show()
        System.out.println("Zi的show()....");
    }
}
public class Demo {
    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();
    }
}
公有靜態方法的衝突
  • 靜態方法是直接屬於接口的,不能被繼承,因此不存在衝突

    interface IA{
        public static  void show(){
            System.out.println("IA");
        }
    }
    interface IB{
        public static void show(){
            System.out.println("IB");
        }
    }
    class Zi implements IA,IB{
    
    }
    public class Demo {
        public static void main(String[] args) {
            Zi z = new Zi();
            z.show();//編譯錯誤,show()不能被繼承。
        }
    }
私有方法的衝突
  • 私有方法只能在本接口中直接使用,不存在衝突

接口與接口之間的關係

  • 接口多繼承時的衝突狀況
    • 公有靜態常量的衝突
    • 公有抽象方法的衝突
    • 公有默認方法的衝突
    • 公有靜態方法和私有方法的衝突

講解

接口與接口之間的關係
  • 接口能夠「繼承」自另外一個「接口」,並且能夠「多繼承」。

    interface IA{}
    interface IB{}
    interface IC extends IA,IB{//是「繼承」,並且能夠「多繼承」
    }
接口繼承接口的衝突狀況
公有靜態常量的衝突
interface IA{
    public static final int a = 10;
    public static final int b = 30;
}
interface IB{
    public static final int a = 20;
}
interface IC extends IA,IB{//沒有繼承a
}
//測試:
main(){
    System.out.println(IC.a);//錯誤的
}
公有抽象方法衝突
interface IA{
    public void show();
}
interface IB{
    public void show();
}
interface IC extends IA,IB{//IC只繼承了一個show()
}
class Zi implements IC{
    //重寫一次show()
    public void show(){
    }
}
公有默認方法的衝突
interface IA{
    public default void d1(){
    }
}
interface IB{
    public default void d1(){
    }
}
interface IC extends IA,IB{//必須重寫一次d1()
    public default  void d1(){
    }
}
公有靜態方法和私有方法
  • 不衝突,由於靜態方法是直接屬於接口的,只能使用接口直接訪問,而私有方法只能在接口中訪問,也沒有衝突

實現類繼承父類又實現接口時的衝突

  • 公有靜態常量的衝突
  • 公有抽象方法的衝突
  • 公有默認方法的衝突
  • 公有靜態方法
  • 私有方法的衝突

講解

父類和接口的公有靜態常量的衝突
class Fu{
    public static final int a = 10;
}
interface IA{
    public static final int a = 20;
}
class Zi extends Fu implements IA{//沒有繼承a變量
}
public class Demo {
    public static void main(String[] args) {
        System.out.println(Zi.a);//編譯錯誤
    }
}
父類和接口的抽象方法衝突
abstract class Fu{
    public abstract void show();
}
interface IA{
    public void show();
}
class Zi extends Fu implements IA{// 必須重寫
    
}
//測試:
main(){
    Zi z = new Zi();
    z.show();//a
}
父類和接口的公有默認方法的衝突
class Fu{
    public void show(){
        System.out.println("a");
    }
}
interface IA{
    public default void show(){
        System.out.println("b");
    }
}
class Zi extends Fu implements IA{
}
//測試:
main(){
    Zi z = new Zi();
    z.show();//a
}
父類和接口的公有靜態方法
class Fu{
    public static void show(){
        System.out.println("fu...");
    }
}
interface IA{
    public static void show(){
        System.out.println("IA...");
    }
}
class Zi extends Fu implements IA{//只繼承了"父類"的靜態方法,沒有繼承接口的靜態方法

}
public class Demo {
    public static void main(String[] args) {
        Zi.show();//fu…
    }
}
父類和接口的私有方法
  • 不存在衝突

實操--抽象類和接口的練習

需求:

經過實例進行分析和代碼演示抽象類和接口的用法。

一、舉例:

​ 犬: --->父類 抽象類

​ 行爲:吼叫;吃飯; ----- 抽象類

​ 緝毒犬: ---> 繼承犬類

​ 行爲:吼叫;吃飯;緝毒;

​ 緝毒接口:

​ 緝毒的功能(抽象方法)

  • 若是全部子類都有的功能: 通用功能(非抽象方法),非通用功能(抽象方法),定義到父類中
  • 若是某個功能是一個類額外增長的,那麼就能夠把這個額外的功能定義到接口中,再這個類去實現

分析:

​ 因爲犬分爲不少種類,他們吼叫和吃飯的方式不同,在描述的時候不能具體化,也就是吼叫和吃飯的行爲不能明確。當描述行爲時,行爲的具體動做不能明確,這時,能夠將這個行爲寫爲抽象行爲,那麼這個類也就是抽象類。

​ 但是有的犬還有其餘額外功能,而這個功能並不在這個事物的體系中 , 例如 : 緝毒犬。緝毒的這個功能有好多種動物都有 , 例如 : 緝毒豬 , 緝毒鼠。咱們能夠將這個額外功能定義接口中 ,讓緝毒犬繼承犬且實現緝毒接口 , 這樣緝毒犬既具有犬科自身特色也有緝毒功能。

  • 額外的功能---> 在接口中定義,讓實現類實現
  • 共性的功能---> 在父類中定義,讓子類繼承

實現:

//定義緝毒接口 緝毒的詞組(anti-Narcotics)比較長,在此使用拼音替代
interface JiDu{
    //緝毒
	public abstract void jiDu();
}
//定義犬科,存放共性功能
abstract class Dog{
    //吃飯
	public abstract void eat();
    //吼叫
	public abstract void roar();
}
//緝毒犬屬於犬科一種,讓其繼承犬科,獲取的犬科的特性,
//因爲緝毒犬具備緝毒功能,那麼它只要實現緝毒接口便可,這樣即保證緝毒犬具有犬科的特性,也擁有了緝毒的功能
class JiDuQuan extends Dog implements JiDu{
	public void jiDu() {
	}
	void eat() {
	}
	void roar() {
	}
}

//緝毒豬
class JiDuZhu implements JiDu{
	public void jiDu() {
	}
}

小結:

  • 額外的功能---> 在接口中定義,讓實現類實現
    • 若是能夠肯定的通用功能,使用默認方法
    • 若是不能肯定的功能,使用抽象方法
  • 共性的功能---> 在父類中定義,讓子類繼承
    • 若是能夠肯定的通用功能,使用默認方法
    • 若是不能肯定的功能,使用抽象方法
相關文章
相關標籤/搜索