最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中接口和抽象類的異同以及具體的使用場(chǎng)景

 更新時(shí)間:2025年11月17日 14:40:15   作者:菜鳥(niǎo)恒  
文章主要介紹了Java中接口(Interface)和抽象類(AbstractClass)的區(qū)別和聯(lián)系,包括相同點(diǎn)和不同點(diǎn),以及它們?cè)趯?shí)際開(kāi)發(fā)中的具體使用場(chǎng)景,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

在 Java 中,接口(Interface) 和 抽象類(Abstract Class) 是實(shí)現(xiàn)抽象編程的核心機(jī)制,二者都用于定義 “規(guī)范” 而非完整實(shí)現(xiàn),但在設(shè)計(jì)理念、語(yǔ)法規(guī)則和使用場(chǎng)景上存在顯著差異。下面從 異同點(diǎn)、核心區(qū)別對(duì)比具體使用場(chǎng)景 三方面詳細(xì)解析。

一、接口和抽象類的 “相同點(diǎn)”

二者的核心目標(biāo)都是 抽象封裝共性行為 / 特征,避免代碼重復(fù),同時(shí)約束子類實(shí)現(xiàn),具體相同點(diǎn)如下:

  1. 都不能實(shí)例化:無(wú)法通過(guò) new 關(guān)鍵字創(chuàng)建對(duì)象(抽象類本質(zhì)是 “不完整的類”,接口是 “純規(guī)范”,均缺少完整實(shí)現(xiàn))。
  2. 都可包含抽象方法:抽象方法是 “只有聲明、沒(méi)有實(shí)現(xiàn)” 的方法(接口中默認(rèn)抽象,抽象類需顯式加 abstract 關(guān)鍵字),子類必須實(shí)現(xiàn)所有抽象方法(否則子類仍為抽象類)。
  3. 都用于被繼承 / 實(shí)現(xiàn):抽象類通過(guò) extends 被繼承,接口通過(guò) implements 被實(shí)現(xiàn),子類 / 實(shí)現(xiàn)類需遵循其定義的規(guī)范。
  4. 都支持多態(tài):可以聲明抽象類 / 接口類型的引用,指向其具體子類 / 實(shí)現(xiàn)類的對(duì)象(核心體現(xiàn) “面向接口編程” 思想)。

示例(多態(tài)共性):

// 抽象類多態(tài)
abstract class Animal {}
class Dog extends Animal {}
Animal animal = new Dog(); // 合法
// 接口多態(tài)
interface Flyable {}
class Bird implements Flyable {}
Flyable flyable = new Bird(); // 合法

二、接口和抽象類的 “核心區(qū)別”

這是重點(diǎn),需從 語(yǔ)法規(guī)則 和 設(shè)計(jì)理念 兩方面區(qū)分,下表是全面對(duì)比:

對(duì)比維度抽象類(Abstract Class)接口(Interface)
繼承 / 實(shí)現(xiàn)方式子類通過(guò) extends 單繼承(Java 不支持多繼承)類通過(guò) implements 多實(shí)現(xiàn)(可同時(shí)實(shí)現(xiàn)多個(gè)接口)
構(gòu)造方法可以有構(gòu)造方法(用于子類初始化時(shí)調(diào)用 super()不能有構(gòu)造方法(接口無(wú) “實(shí)例狀態(tài)”,僅定義規(guī)范)
成員變量可包含任意成員變量(public/private/protected、靜態(tài) / 非靜態(tài))只能是 public static final 常量(默認(rèn)隱式修飾,必須初始化)
成員方法

1. 抽象方法(abstract 修飾);

2. 普通非抽象方法(有方法體);3. JDK8+ 支持默認(rèn)方法(default)和靜態(tài)方法(static

1. JDK7-:只能是抽象方法(默認(rèn) public abstract);

2. JDK8+:支持默認(rèn)方法(default)和靜態(tài)方法(static);

3. JDK9+:支持私有方法(private,用于內(nèi)部復(fù)用)

訪問(wèn)權(quán)限成員可聲明任意權(quán)限(private/protected/public所有成員(方法、常量)默認(rèn) public(顯式聲明也只能是 public
設(shè)計(jì)理念體現(xiàn) “is-a” 關(guān)系(子類是抽象類的 “一種具體實(shí)現(xiàn)”,包含繼承的屬性和行為)體現(xiàn) “has-a” 關(guān)系(類 “具備” 接口定義的功能,是對(duì)行為的補(bǔ)充擴(kuò)展)
核心作用封裝子類的共性屬性和行為(既有抽象規(guī)范,也有具體實(shí)現(xiàn)復(fù)用)定義純行為規(guī)范(不關(guān)心類的本質(zhì),只約束必須實(shí)現(xiàn)的功能)
靈活性單繼承限制,靈活性低多實(shí)現(xiàn) + 接口繼承(extends 多個(gè)接口),靈活性高

關(guān)鍵區(qū)別詳解(避免踩坑)

繼承限制:抽象類只能單繼承(子類 extends 一個(gè)抽象類),接口支持多實(shí)現(xiàn)(類 implements A, B)+ 接口多繼承(接口 extends A, B)。示例(接口多繼承):

interface Runable { void run(); }
interface Flyable { void fly(); }
// 接口可繼承多個(gè)接口,合并規(guī)范
interface SuperAbility extends Runable, Flyable {}
// 類可實(shí)現(xiàn)多個(gè)接口,實(shí)現(xiàn)所有抽象方法
class Superman implements SuperAbility {
    @Override 
    public void run() {}
    @Override 
    public void fly() {}
}

成員變量差異

  • 抽象類的變量可修改(非 final):
    abstract class Person {
        protected String name; // 可被子類修改
        public static int age = 18; // 靜態(tài)變量可直接訪問(wèn)
    }
    
  • 接口的變量默認(rèn)是 public static final(必須初始化,不可修改):
    interface Constants {
        String NAME = "Java"; // 等價(jià)于 public static final String NAME = "Java";
        // int NUM; // 編譯報(bào)錯(cuò):必須初始化
    }
    

方法實(shí)現(xiàn)差異

抽象類的普通方法可直接被子類復(fù)用:

abstract class Vehicle {
    // 具體方法(子類可直接使用,無(wú)需重寫(xiě))
    public void refuel() {
        System.out.println("加油...");
    }
    // 抽象方法(子類必須實(shí)現(xiàn))
    public abstract void drive();
}
class Car extends Vehicle {
    @Override 
    public void drive() { 
        System.out.println("開(kāi)車..."); 
    }
}
Car car = new Car();
car.refuel(); // 直接復(fù)用父類方法,輸出“加油...”

接口的默認(rèn)方法(JDK8+)是為了 “接口升級(jí)不破壞原有實(shí)現(xiàn)類”,實(shí)現(xiàn)類可重寫(xiě):

interface Greet {
    default void sayHello() {
        System.out.println("Hello");
    }
}
class Chinese implements Greet {
    // 可選重寫(xiě)默認(rèn)方法
    @Override 
    public void sayHello() {
        System.out.println("你好");
    }
}

三、具體使用場(chǎng)景(核心:選對(duì)設(shè)計(jì)方向)

選擇接口還是抽象類,核心看 你要表達(dá)的是 “繼承關(guān)系” 還是 “功能擴(kuò)展”,以及是否需要復(fù)用具體實(shí)現(xiàn)。

1. 優(yōu)先使用抽象類的場(chǎng)景

當(dāng)你需要定義一個(gè) “類的模板”,子類和父類是 “is-a” 關(guān)系,且需要復(fù)用 屬性或具體方法 時(shí),用抽象類。典型場(chǎng)景:

共性屬性 + 行為復(fù)用:例如 Animal 抽象類(子類 Dog/Cat 是 “一種動(dòng)物”),包含 name 屬性和 eat() 具體方法(所有動(dòng)物都要吃飯,實(shí)現(xiàn)相同),同時(shí)定義 makeSound() 抽象方法(不同動(dòng)物叫聲不同,子類實(shí)現(xiàn))。

abstract class Animal {
    protected String name;
    // 具體方法:復(fù)用實(shí)現(xiàn)
    public void eat() {
        System.out.println(name + "在吃飯");
    }
    // 抽象方法:約束子類實(shí)現(xiàn)
    public abstract void makeSound();
}
class Dog extends Animal {
    public Dog(String name) {
        this.name = name; 
    }
    @Override 
    public void makeSound() { 
        System.out.println("汪汪叫"); 
    }
}
class Cat extends Animal {
    public Cat(String name) { 
        this.name = name; 
    }
    @Override 
    public void makeSound() { 
        System.out.println("喵喵叫"); 
    }
}
  • 需要構(gòu)造方法初始化:抽象類的構(gòu)造方法可用于子類初始化(例如通過(guò) super(name) 給父類屬性賦值),接口無(wú)構(gòu)造方法,無(wú)法實(shí)現(xiàn)。
  • 限制子類數(shù)量:?jiǎn)卫^承特性可避免子類過(guò)度擴(kuò)展(例如 HttpServlet 抽象類,子類只需重寫(xiě) doGet()/doPost(),無(wú)需關(guān)注其他 Servlet 生命周期方法)。

2. 優(yōu)先使用接口的場(chǎng)景

當(dāng)你需要定義 “功能規(guī)范”,類和接口是 “has-a” 關(guān)系,且需要 多實(shí)現(xiàn)擴(kuò)展 或 跨類層次復(fù)用行為 時(shí),用接口。典型場(chǎng)景:

定義純行為規(guī)范(不關(guān)心類的本質(zhì)):例如 Runnable 接口(只要求類實(shí)現(xiàn) run() 方法,不管是 Thread、Task 還是其他類)、Comparable 接口(只要求類實(shí)現(xiàn)比較邏輯)。

// 接口定義“可比較”規(guī)范
interface Comparable<T> {
    int compareTo(T o);
}
// 任意類都可實(shí)現(xiàn)該接口,獲得比較能力(跨類層次復(fù)用)
class Student implements Comparable<Student> {
    private int score;
    @Override 
    public int compareTo(Student o) {
        return this.score - o.score;
    }
}
class Product implements Comparable<Product> {
    private double price;
    @Override 
    public int compareTo(Product o) {
        return Double.compare(this.price, o.price);
    }
}
  • 多功能擴(kuò)展:一個(gè)類需要具備多種無(wú)關(guān)功能時(shí),通過(guò)多實(shí)現(xiàn)接口實(shí)現(xiàn)(例如 Superman 類同時(shí)實(shí)現(xiàn) Runable、Flyable、Swimable 接口,獲得跑、飛、游泳三種能力)。
  • 接口回調(diào) / 解耦:例如 Spring 框架的 ApplicationContextAware 接口(實(shí)現(xiàn)類可獲取 ApplicationContext 對(duì)象),框架通過(guò)接口規(guī)范調(diào)用方法,無(wú)需關(guān)心實(shí)現(xiàn)類的具體類型,降低耦合。
  • 接口升級(jí)(默認(rèn)方法):JDK8 后,接口可通過(guò) default 方法添加新功能,而不破壞原有實(shí)現(xiàn)類(例如 Collection 接口新增 stream() default 方法,所有集合實(shí)現(xiàn)類無(wú)需修改即可使用)。

3. 抽象類和接口結(jié)合使用(最佳實(shí)踐)

實(shí)際開(kāi)發(fā)中,常結(jié)合二者的優(yōu)勢(shì):抽象類提供基礎(chǔ)實(shí)現(xiàn),接口定義擴(kuò)展功能。典型示例:Java 集合框架中的 AbstractCollection(抽象類)和 Collection(接口)。

  • Collection 接口:定義所有集合的核心規(guī)范(add()size()、iterator() 等抽象方法),不關(guān)心實(shí)現(xiàn)。
  • AbstractCollection 抽象類:實(shí)現(xiàn) Collection 接口的部分方法(例如 isEmpty()contains()),復(fù)用基礎(chǔ)邏輯,子類(如 ArrayListLinkedList)只需重寫(xiě)核心方法(add()、iterator())即可。

代碼簡(jiǎn)化示例:

// 接口:定義規(guī)范
interface Collection {
    boolean add(Object obj);
    int size();
    boolean isEmpty();
}
// 抽象類:實(shí)現(xiàn)通用方法,減少子類重復(fù)代碼
abstract class AbstractCollection implements Collection {
    private int size = 0;
    @Override public boolean add(Object obj) {
        // 子類需實(shí)現(xiàn)具體添加邏輯,但size遞增可復(fù)用
        doAdd(obj);
        size++;
        return true;
    }
    @Override public int size() { return size; }
    @Override public boolean isEmpty() { return size == 0; }
    // 抽象方法:子類必須實(shí)現(xiàn)具體添加邏輯
    protected abstract void doAdd(Object obj);
}
// 具體子類:只需關(guān)注核心實(shí)現(xiàn)
class MyList extends AbstractCollection {
    private Object[] elements = new Object[10];
    @Override protected void doAdd(Object obj) {
        // 實(shí)現(xiàn)數(shù)組添加邏輯
        for (int i = 0; i < elements.length; i++) {
            if (elements[i] == null) {
                elements[i] = obj;
                break;
            }
        }
    }
}

四、總結(jié)(核心選型口訣)

  1. 若子類和父類是 “is-a” 關(guān)系,需復(fù)用屬性或具體方法 → 用 抽象類;
  2. 若類需要具備多種無(wú)關(guān)功能,或定義純行為規(guī)范 → 用 接口;
  3. 若需既保證基礎(chǔ)實(shí)現(xiàn)復(fù)用,又支持靈活擴(kuò)展 → 抽象類 + 接口 結(jié)合使用。

本質(zhì)區(qū)別:抽象類是 “類的模板”,側(cè)重繼承和復(fù)用;接口是 “行為的契約”,側(cè)重規(guī)范和擴(kuò)展。遵循 “面向接口編程” 的設(shè)計(jì)思想,優(yōu)先使用接口(解耦、靈活),僅在需要復(fù)用具體實(shí)現(xiàn)時(shí)才用抽象類。

到此這篇關(guān)于Java中接口和抽象類的異同以及具體的使用場(chǎng)景的文章就介紹到這了,更多相關(guān)java接口和抽象類使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Security 中如何讓上級(jí)擁有下級(jí)的所有權(quán)限(案例分析)

    Spring Security 中如何讓上級(jí)擁有下級(jí)的所有權(quán)限(案例分析)

    這篇文章主要介紹了Spring Security 中如何讓上級(jí)擁有下級(jí)的所有權(quán)限,本文通過(guò)案例分析給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java中的接口以及常見(jiàn)的Cloneable接口用法

    Java中的接口以及常見(jiàn)的Cloneable接口用法

    這篇文章主要介紹了Java中的接口以及常見(jiàn)的Cloneable接口用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • java使用Runtime.getRuntime().exec調(diào)用外部程序

    java使用Runtime.getRuntime().exec調(diào)用外部程序

    Runtime.getRuntime().exec一般用于調(diào)用外部可執(zhí)行程序或系統(tǒng)命令,并重定向外部程序的標(biāo)準(zhǔn)輸入,準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤到緩沖池,下面我們來(lái)看看Java如何使用它進(jìn)行調(diào)用外部程序吧
    2025-06-06
  • Spring Boot 配置MySQL數(shù)據(jù)庫(kù)重連的操作方法

    Spring Boot 配置MySQL數(shù)據(jù)庫(kù)重連的操作方法

    這篇文章主要介紹了Spring Boot 配置MySQL數(shù)據(jù)庫(kù)重連的操作方法,需要的朋友可以參考下
    2018-04-04
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(25)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(25)

    下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你
    2021-07-07
  • Spring實(shí)戰(zhàn)之FileSystemResource加載資源文件示例

    Spring實(shí)戰(zhàn)之FileSystemResource加載資源文件示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之FileSystemResource加載資源文件,結(jié)合實(shí)例形式分析了spring FileSystemResource加載xml資源文件的具體實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2019-12-12
  • spring boot如何添加攔截器

    spring boot如何添加攔截器

    本篇文章主要介紹了spring boot如何添加攔截器,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • Maven引入與打包指定目錄下的第三方sdk的幾種方法

    Maven引入與打包指定目錄下的第三方sdk的幾種方法

    本文主要介紹了Maven引入與打包指定目錄下的第三方sdk的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • 實(shí)例講解Java中動(dòng)態(tài)代理和反射機(jī)制

    實(shí)例講解Java中動(dòng)態(tài)代理和反射機(jī)制

    在本篇文章里小編給各位分享了關(guān)于Java中動(dòng)態(tài)代理和反射機(jī)制的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們學(xué)習(xí)下。
    2019-01-01
  • 淺談SpringBoot中的@Conditional注解的使用

    淺談SpringBoot中的@Conditional注解的使用

    這篇文章主要介紹了淺談SpringBoot中的@Conditional注解的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04

最新評(píng)論

博兴县| 新宁县| 乐至县| 光山县| 杨浦区| 宣恩县| 泽普县| 松阳县| 庄河市| 南京市| 石河子市| 怀安县| 聊城市| 莫力| 平安县| 永定县| 柞水县| 莎车县| 靖西县| 隆昌县| 乐陵市| 罗山县| 扎鲁特旗| 贞丰县| 高唐县| 尼勒克县| 两当县| 柳州市| 云南省| 东阿县| 察隅县| 东安县| 望江县| 尼玛县| 吕梁市| 靖西县| 精河县| 建德市| 铜鼓县| 理塘县| 新津县|