日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java接口学习(接口的使用、简单工厂、代理模式、接口和抽象类的区别)

發布時間:2025/3/12 java 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java接口学习(接口的使用、简单工厂、代理模式、接口和抽象类的区别) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言引入

官方解釋:Java接口是一系列方法的聲明,是一些方法特征的集合,一個接口只有方法的特征沒有方法的實現,因此這些方法可以在不同的地方被不同的類實現,而這些實現可以具有不同的行為(功能)。

我的理解:接口可以理解為一種特殊的抽象類,里面全部是由全局常量和公共的抽象方法所組成。接口是解決Java無法使用多繼承的一種手段,可以實現多個接口的實現,但是接口在實際中更多的作用是制定標準的。或者我們可以直接把接口理解為100%的抽象類,接口中的方法必須全部是抽象方法。

一、接口的基本概念與主要特點;
二、接口的使用;
三、接口應用:簡單工廠設計模式、代理設計模式簡單實現。

一、接口的基本概念與主要特點

  • 如果一個類中只是由抽象方法和全局變量所組成,那么在這種情況下不會定義為抽象類,而會定義為接口,接口嚴格來講是一個抽象類,而且這個類里面只有抽象方法和全局變量,沒有構造方法。

1.1 接口特點

就像一個類一樣,一個接口也能夠擁有方法和屬性,但是在接口中聲明的方法默認是抽象的。(即只有方法標識符,而沒有方法體)。

  • 接口不能實例化,可以按照多態的方式來實例化;
  • 接口沒有構造方法;
  • 接口指明了一個類必須要做什么和不能做什么,相當于類的行為的規劃;
  • 一個接口就是描述一種能力,比如 “Animal” 也可以作為一個接口,并且任何實現“Animal”接口的類都必須有能力實現 “奔跑”這個動作(或者implement run()方法),所以接口的作用就是告訴類,你要實現我這種接口代表的功能,你就必須實現某些方法,我才能承認你確實擁有該接口代表的某種能力;
  • 如果一個類實現了一個接口中要求的所有的方法,然而沒有提供方法體而僅僅只有方法標識,那么這個類一定是一個抽象類。(牢記:抽象方法只能存在于抽象類或者接口中,但抽象類中卻能存在非抽象方法,即有方法體的方法。接口是百分之百的抽象類)

一個JAVA庫中接口的例子是:Iterator 接口,這個接口代表了“能夠進行迭代遍歷”這種能力,任何類只要實現了這個 “ Iterator” 接口的話,這個類也具備了 “迭代遍歷” 這種能力,那么就可以用來進行元素遍歷操作了。

1.2 為什么要用接口

  • 接口被用來描述一種抽象,表達的一種 “ has - a” 關系,方便以后功能的擴展。
  • Java可以通過實現接口來彌補單繼承局限。
  • 接口用來實現解耦,制定一種標準。
  • 接口定義的變量一定是public static final 的,實現 此接口的類都可以使用這個變量。
  • 二、接口的使用

    2.1 接口的定義

    要定義一個接口使用 interface 關鍵字完成。

    interface A{ // 定義接口public static final String MSG="hello";// 抽象方法public abstract void print(); }

    由于接口里面存在有抽象方法,所以接口對象不能用關鍵字new進行實例化的操作。先說幾個接口使用的限制:

    • 接口必須要有子類實現,此時一個子類可以使用implement關鍵字實現多個接口;
    • 接口的子類(如果不是抽象類),必須要覆寫接口中的全部抽象方法;
    • 接口中的對象可以利用子類對象的向上轉型進行實例化的操作。

    范例:實現接口

    interface A { // 定義了接口public static final String MSG = "hello";// 抽象方法public abstract void print(); } interface B {public abstract void get(); } class X implements A,B { // 實現多個接口public void get() {System.out.println("B接口的抽象方法");}public void print() {System.out.println("A接口的抽象方法");} } public class TestDemo {public static void main(String args[]){X x = new C();//實例化子類對象A a = x;B b = x;// A a = new X();//向上轉型// B b = new X();//向上轉型a.print();b.get();} }

    以上的代碼實例化了 “x” 對象,由于 X 是 A 和 B 的子類,那么 X 類對象可以變為 A 接口或 B 接口類的對象。

    在定義上 A 和 B 接口沒有任何的直接聯系,但是這兩個接口卻同時擁有一個子類: X 子類,不要被類型和名稱所迷惑,因為最終實例化的 X 的子類,而這個子類屬于 B 類的對象,所以以上的代碼行的通,代碼編寫上并不是很友好。

    • 子類除了可以實現接口,還可能去繼承抽象類,所以說一個子類又要繼承抽象類,還要實現接口的話,先使用extends繼承,而后使用implements實現。

    2.2 子類繼承和接口實現使用

    代碼示例(即有繼承關系又有接口實現)

    interface A { // 定義了接口public static final String MSG = "hello";// 抽象方法public abstract void print();}interface B {public abstract void get();}abstract class C { // 定義一個抽象類public abstract void change();}class X extends C implements A,B {//先繼承,再實現接口public void get() {System.out.println("B接口的抽象方法");}public void print() {System.out.println("A接口的抽象方法");}public void change(){System.out.println("C類的抽象方法");}}

    對接口而言,發現里面的組成是抽象方法和全局變量,所以很多的時候有些人為了簡略不會寫 abstract 和 public static final,并且在方法上是否編寫 public 結果都是一樣的,因為在接口里面只能夠使用一種訪問權限——public。以下兩個接口的定義效果是一樣的:

    interface A{public static final String MSG="HELLO";public void fun(); } // 另一種定義方式 ,常量的話 我們 一般 寫成 public static final String MSG = “Hello”; Interface A{String MSG=”HELLO”;void fun(); }

    一個抽象類可以繼承一個抽象類,一個接口可以使用extends關鍵字同時繼承多個接口,接口不可以繼承抽象類。

    2.3 接口的多繼承

    范例:接口的多繼承

    interface A {public void funA(); } interface B {public void funB(); } interface C extends A,B {public void funC(); } class X implements C {public void funA() { } // 覆寫全部的方法public void funB() { }public void funC() { } }

    從繼承關系上講接口比抽象類的優勢明顯:

    • 一個抽象類只能繼承一個抽象類,而接口沒有這個限制;
    • 一個子類只能夠繼承一個抽象類,而卻可以實現多個接口。

    在java中,接口解決了單繼承的局限性問題。 雖然從接口本身的概念來講只能夠由抽象方法和全局變量所組成,但是所有的內部結構不受這些要求的限制,也就是說在接口中可以定義普通內部類、抽象內部類、內部接口。

    2.4 在接口中定義抽象類和 static 接口

    范例:在接口里定義抽象類

    interface A{public void funA();// 獨立的class文件,abstract class B{// 在接口中的abstract可以不用寫,但在抽象類中的抽象方法必須要寫abstractpublic abstract void funB();}interface Entry { // 接口中定義接口 ,Map.Entry HashMap 源碼 Collection 中的 Iterator 接口} } class X implements A { // X 實現了A接口public void funA() {System.out.println("Hello World");}class Y extends B { // 內部類 Y繼承了抽象類 B 實現了 funB() 方法public void funB () {System.out.println("hello C");} } }

    在接口中定義static接口

    interface A {public void funA();// static聲明的內部接口為外部接口,static聲明的內部類為外部類static interface B{ // 外部接口,public void funB();}}class X implements A.B{ // 實現時使用“類名.內部接口”public void funB() {}

    先期總結:接口在實際的開發中三大核心作用:

    • 定義不同層之間的操作標準;
    • 表示一種操作的能力;
    • 表示將服務端的遠程方法視圖暴露給客戶。

    2.5 接口中的實際應用——標準

    電腦上可以使用U盤、Mp3、打印機,這些設備都是連接到USB設備上的。

    • 所有的代碼如果要進行開發,一定要首先開發出USB接口標準,因為有了標準后電腦才可以去使用這些標準,設備廠商才可以設計USB設備。

    范例:定義USB標準(標準可以連接不同層的操作)

    // 標準可以連接不同層的操作 interface USB { // 定義標準一定是接口public void start();public void stop(); }

    范例:定義電腦
    不管以后有多少個設備,只要它是 USB 標準的實現子類,它都可以在電腦上使用。

    class Computer {public void plugin(USB usb){//插入usb.start();usb.stop();} }

    范例:定義U盤

    class Flash implements USB {public void start(){System.out.println("U盤開始使用");}public void stop(){System.out.println("u盤停止使用");} }

    范例:定義打印機

    class Print implements USB {public void start(){System.out.println("打印機開始工作");}public void stop(){System.out.println("打印機停止工作");} }

    按照這樣的方式,準備好多個子類都可以在電腦的plugin()方法上使用

    interface USB{//定義標準一定是接口public void start();public void stop(); } class Computer {public void plugin(USB usb){//插入usb.start();usb.stop();} } class Flash implements USB{public void start(){System.out.println("U盤開始使用");}public void stop(){System.out.println("u盤停止使用");} } class Print implements USB{public void start(){System.out.println("打印機開始工作");}public void stop(){System.out.println("打印機停止工作");} } public class TestDemo {public static void main(String args[]){Computer com = new Computer();com.plugin(new Flash());com.plugin(new Print());} }

    在現實生活中,標準的概念隨處可見,而在程序里面標準就是用接口來實現的。

    三、接口的應用(簡單工廠和代理)

    3.1 接口的應用——工廠設計模式(Factory 簡單介紹)

    下面觀察一段程序代碼

    interface Fruit {public void eat(); } class Apple implements Fruit {public void eat() {System.out.println("吃蘋果");} } public class TestDemo {public static void main(String args[]){Fruit f = new Apple();f.eat(); }

    以上的程序可以通過主方法得到Fruit接口對象,這種代碼設計有問題嗎?
    本端程序的問題就是出現了關鍵字“new”。

    評判一段代碼是否真的好,有這么幾個標準:

    • 客戶端可以調用,不需要關注具體的細節;

    • 客戶端之外的代碼修改,不影響用戶端的使用,即:用戶端可以不關
      心代碼是否變更。
      一個接口不可能只有一個子類,對于Fruit也有可能產生多個子類對象(Apple,Orange)。

    現在每次客戶端想要得到新的子類對象,都需要修改代碼,如果在客戶端實例化對象,那么每一要更換對象對象,都需要修改客戶端上的代碼,這樣的做法是不友好的。

    • 現在要解決是如何得到一個Fruit接口對象,而后進行方法的調用,至于這個接口對象是被誰實例化的,不是我客戶端的工作。現在最大的問題在于關鍵字new,這一問題可以理解為耦合度太高。耦合度太高的直接問題就是代碼不方便維護,相當于A與B綁定在一起。

    程序 -> JVM -> 適應不同的操作系統(A->C->B)

    范例:增加一個過渡

    class Factory {public static Fruit getInstance(String className){if ("apple".equals(className)) {return new Apple();} else if ("orange".equals(className)) {return new Orange();} else {return null;}} } public class TestDemo {public static void main(String args[]){Fruit f = Factory.getInstance("apple");f.eat();} }
    • 現在的客戶端不會看見具體的子類,因為所有的接口對象都是通過Factory類取得子類對象,則只需要修改Factory類即可,但是客戶端不會發生變化。

    工廠類跟操作的接口類有關,也跟所有的子類有關;客戶端可看見接口,還可以看見工廠,客戶端使用getInstance()方法找到工廠類中定義的方法,這個方法返回接口對象,通過接口對象就可以獲得接口中的操作方法。

    面試題:請編寫一個Factory程序

    3.2 接口的應用——代理設計模式(Proxy簡單介紹)

    皇帝寵幸妃子的為例,具體步驟圖中已經列出。

    范例:轉換為程序

    interface Subject { // 整個操作的核心public void makeLove(); // 整個臨幸的核心功能 } class RealSubject implements Subject { // 一個接口兩個主題 public void makeLove() {System.out.println("正在");} } class ProxySubject implements Subject {//內務private Subject subject;// 要接受一個真正主題的操作對象public ProxySubject(Subject subject){this.subject = subject;}public void prepare(){ // 擴展的功能System.out.println("為臨幸做準備");}public void makeLove() {this.prepare();this.subject.makeLove(); // 告訴皇帝可以開始了this.end();}public void end() { // 擴展的功能System.out.println("娘娘帶走,皇帝睡覺");} } public class TestDemo {public static void main(String args[]){Subject sub = new ProxySubject(new RealSubject());sub.makeLove();//調用的是代理操作} }
    • 代理設計模式的核心精髓就在于一個主題操作接口(可能有多種方法),核心業務主題只完成核心功能。而代理主題負責所有與核心主題有關的輔助型操作。


    代理模式的主要角色如下。

    • 代理主題類(Subject ):通過接口或抽象類聲明真實主題和代理對象實現的業務方法。

    • 真實主題類(RealSubject):實現了抽象主題中的具體業務,是代理對象所代表的真實對象,是最終要引用的對象。

    • 代理(ProxySubject)類:提供了與真實主題相同的接口,其內部含有對真實主題的引用,它可以訪問、控制或擴展真實主題的功能。

    使用代理(靜態代理)的目的和缺陷:

    • 可以做到在不修改目標對象的功能前提下,對目標功能擴展.

    缺點:

    • 因為代理對象需要與目標對象實現一樣的接口,所以會有很多代理類,類太多.同時,一旦接口增加方法,目標對象與代理對象都要維護.

    面試題:請編寫一個Proxy模式程序

    四、抽象類與接口的區別(面試題)

    抽象類和接口使用的形式上是十分相似的。

    4.1 表格對比

    4.2 文字描述

    接口與抽象類的區別:

    • 抽象類是對一種事物的抽象,即對類抽象,而接口是對行為的抽象,也就是對方法的抽象。

    • 抽象類可以有具體的成員方法,而接口中只能存在抽象方法;

    • 抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是public static final類型的;

    • 接口中不能含有靜態代碼塊以及靜態方法,而抽象類可以有靜態代碼塊和靜態方法;

    • 一個類只能繼承一個抽象類,而一個類卻可以實現多個接口。

    • 抽象類如果需要添加新的方法,可以直接在抽象類中添加具體的實現,子類可以不進行變更;而接口進行了變更,則所有實現這個接口的類都必須進行相應的改動(功能擴展)。經過比較可以發現,抽象類中支持的功能絕對要比接口更多,但是抽象類有單繼承局限性。

    代碼編寫的習慣:

    • 在進行某些公共操作的時候一定要定義出接口;
    • 有了接口后需利用子類完善方法;
    • 如果是自己寫的接口,絕對不要使用關鍵字new直接實例化接口子類,使用工廠類完成。

    四、總結

  • 接口的基本使用;
  • 接口作為標準用于解耦和以及不同層之間的連接橋梁;
  • 工廠設計模式與代理設計模式的簡單介紹;
  • 接口與抽象類定義的不同。
  • 參考文檔:https://www.cnblogs.com/qmdx00/p/7469379.html
    https://blog.csdn.net/qq_19782019/article/details/80259836

    總結

    以上是生活随笔為你收集整理的Java接口学习(接口的使用、简单工厂、代理模式、接口和抽象类的区别)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。