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

Java中抽象類和接口的用法詳解

 更新時間:2022年08月19日 10:07:48   作者:XIN-XIANG榮  
這篇文章主要為大家詳細介紹了Java中抽象類和接口的使用,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

一. 抽象類

在面向?qū)ο蟮母拍钪?,所有的對象都是通過類來描繪的,但是反過來,并不是所有的類都是用來描繪對象的,如果 一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。

1. 抽象類的語法

在Java中,一個類如果被 abstract 修飾稱為抽象類,抽象類中被 abstract 修飾的方法稱為抽象方法,抽象方法不用給出具體的實現(xiàn)體。

抽象類也是類,內(nèi)部可以包含普通方法和屬性,甚至構(gòu)造方法

// 抽象類:被abstract修飾的類
public abstract class Shape {
    // 抽象方法:被abstract修飾的方法,沒有方法體
    abstract public void draw();
    abstract void calcArea();
    // 抽象類也是類,也可以增加普通方法和屬性
    protected double area; // 面積
    public double getArea(){
        return area;
    }
}

2. 抽象類的特性

  • 抽象類使用abstract來修飾
  • 抽象類當中可以包含普通類所能包含的成員,可以包含抽象方法
  • 抽象方法使用abstract修飾,這個方法沒有具體的實現(xiàn)
  • 抽象方法沒有加訪問限定符時,默認是public.
  • 抽象類不可以被實例化
  • 抽象方法不能被private、static、final修飾, 因為抽象方法要被子類重寫 ,要滿足重寫的規(guī)則
  • 抽象類存在的最大意義就是為了被繼承
  • 如果一個普通類繼承了一個抽象類,此時必須重寫抽象類中的抽象方法
  • 如果一個抽象類A繼承了一個抽象類B,此時A當中可以不重寫B(tài)中的抽象方法;但是如果再被普通類繼承,就需要重寫A和B中所有的抽象方法
  • 抽象類中不一定包含抽象方法,但是有抽象方法的類一定是抽象類
  • 抽象類中可以有構(gòu)造方法,供子類創(chuàng)建對象時,初始化抽象類的成員變量
abstract class Shape {
    //抽象方法
    public abstract void draw();
}

class Rect extends Shape {
    @Override
    public void draw() {
        System.out.println("畫一個矩形!");
    }
}

class Cycle extends Shape {
    @Override
    public void draw() {
        System.out.println("畫一個圓!");
    }
}

class Triangle extends Shape {
    @Override
    public void draw() {
        System.out.println("畫一個三角形!");
    }
}

class Flower extends Shape {
    @Override
    public void draw() {
        System.out.println("畫一朵?!");
    }
}

public class Test {
    //向上轉(zhuǎn)型實現(xiàn)多態(tài)
    public static void drawMap(Shape shape) {
        shape.draw();
    }
    public static void main(String[] args) {
        Rect rect = new Rect();
        drawMap(rect);
        drawMap(new Cycle());
        drawMap(new Triangle());
        drawMap(new Flower());
    }
}

3. 抽象類的作用

抽象類本身不能被實例化, 要想使用, 只能創(chuàng)建該抽象類的子類. 然后讓子類重寫抽象類中的抽象方法; 使用抽象類相當于多了一重編譯器的校驗。

使用抽象類的場景思考,代碼中的實際工作不應(yīng)該由父類完成, 而應(yīng)由子類完成;那么此時如果不小心誤用成父類 了, 使用普通類編譯器是不會報錯的;但是父類是抽象類就會在實例化的時候提示錯誤, 讓我們盡早發(fā)現(xiàn)問題.

很多語法存在的意義都是為了 “預(yù)防出錯”, 例如 final 關(guān)鍵字也是類似;創(chuàng)建的變量用戶不去修改, 不 就相當于常量嘛? 但是加上 final 能夠在不小心誤修改的時候, 讓編譯器及時提醒我們.

充分利用編譯器的校驗, 在實際開發(fā)中是非常有意義的.

二. 接口

1. 接口的概念

在現(xiàn)實生活中,接口的例子比比皆是,比如:筆記本上的USB口,電源插座等。

電腦的USB口上,可以插:U盤、鼠標、鍵盤…所有符合USB協(xié)議的設(shè)備

電源插座插孔上,可以插:電腦、電視機、電飯煲…所有符合規(guī)范的設(shè)備

通過上述例子可以看出:接口就是公共的行為規(guī)范標準,大家在實現(xiàn)時,只要符合規(guī)范標準,就可以通用。

在Java中,接口可以看成是:多個類的公共規(guī)范,是一種引用數(shù)據(jù)類型。

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

接口可以理解為一種特殊的類,里面全部是由全局常量和公共的抽象方法所組成。接口是解決Java無法使用多繼承的一種手段,但是接口在實際中更多的作用是制定標準的?;蛘呶覀兛梢灾苯影呀涌诶斫鉃?00%的抽象類,既接口中的方法必須全部是抽象方法。(JDK1.8之前可以這樣理解)

2. 語法規(guī)則

接口的定義格式與定義類的格式基本相同,將class關(guān)鍵字換成 interface關(guān)鍵字,就定義了一個接口。

public interface 接口名稱{
    // 抽象方法
    public abstract void method1(); 
    // public abstract 是固定搭配,可以不寫
    public void method2();
    abstract void method3();
    void method4();
    // 注意:在接口中上述寫法都是抽象方法,跟推薦方式4,代碼更簡潔
}

小建議:

創(chuàng)建接口時, 接口的命名一般以大寫字母 I 開頭.

接口的命名一般使用 “形容詞” 詞性的單詞.

阿里編碼規(guī)范中約定, 接口中的方法和屬性不要加任何修飾符號, 保持代碼的簡潔性.

3. 接口的使用

接口不能直接使用,必須要有一個"實現(xiàn)類"來"實現(xiàn)"該接口,實現(xiàn)接口中的所有抽象方法。

子類和父類之間是extends 繼承關(guān)系,類與接口之間是 implements 實現(xiàn)關(guān)系。

public class 類名稱 implements 接口名稱{
// ...
}

請實現(xiàn)筆記本電腦使用USB鼠標、USB鍵盤的例子

  1. USB接口:包含打開設(shè)備、關(guān)閉設(shè)備功能
  2. 筆記本類:包含開機功能、關(guān)機功能、使用USB設(shè)備功能
  3. 鼠標類:實現(xiàn)USB接口,并具備點擊功能
  4. 鍵盤類:實現(xiàn)USB接口,并具備輸入功能
// USB接口
public interface USB {
    void openDevice();
    void closeDevice();
}
// 鼠標類,實現(xiàn)USB接口
public class Mouse implements USB {
    @Override
    public void openDevice() {
        System.out.println("打開鼠標");
    }
    @Override
    public void closeDevice() {
        System.out.println("關(guān)閉鼠標");
    }
    public void click(){
        System.out.println("鼠標點擊");
    }
}
// 鍵盤類,實現(xiàn)USB接口
public class KeyBoard implements USB {
    @Override
    public void openDevice() {
        System.out.println("打開鍵盤");
    }
    @Override
    public void closeDevice() {
        System.out.println("關(guān)閉鍵盤");
    }
    public void inPut(){
        System.out.println("鍵盤輸入");
    }
}
// 筆記本類:使用USB設(shè)備
public class Computer {
    public void powerOn(){
        System.out.println("打開筆記本電腦");
    }
    public void powerOff(){
        System.out.println("關(guān)閉筆記本電腦");
    }
    public void useDevice(USB usb){
        usb.openDevice();
        if(usb instanceof Mouse){
            Mouse mouse = (Mouse)usb;
            mouse.click();
        }else if(usb instanceof KeyBoard){
            KeyBoard keyBoard = (KeyBoard)usb;
            keyBoard.inPut();
        }
        usb.closeDevice();
    }
}

// 測試類:
public class TestUSB {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.powerOn();
        // 使用鼠標設(shè)備
        computer.useDevice(new Mouse());
        // 使用鍵盤設(shè)備
        computer.useDevice(new KeyBoard());
        computer.powerOff();
    }
}

4. 接口的特性

1.接口類型是一種引用類型,使用interface來修飾,但是不能直接new接口的對象

2.類和接口之間用implements來實現(xiàn)

3.接口中每一個方法都是public的抽象方法, 即接口中的方法會被隱式的指定為 public abstract(只能是public abstract,其他修飾符都會報錯)

  • 要注意的是從JDK1.8開始,允許有可以實現(xiàn)的方法,但這個方法只能是由default修飾的
  • JDK1.8中: 接口中可以有靜態(tài)的方法

4.接口中的方法是不能在接口中實現(xiàn)的,只能由實現(xiàn)接口的類來實現(xiàn)

5.重寫接口中方法時,不能使用default訪問權(quán)限修飾

6.接口中可以含有變量,但是接口中的變量會被隱式的(默認)指定為 public static final 變量

7.實現(xiàn)類重寫接口中的抽象方法,必須加上public來修飾

8.接口中不能有靜態(tài)代碼塊和構(gòu)造方法

9.接口雖然不是類,但是接口編譯完成后字節(jié)碼文件的后綴格式也是.class

10.如果不想實現(xiàn)接口當中的抽象方法,那么實現(xiàn)類必須設(shè)置為抽象類;但是如果這個類再被其它類繼承,那么必須重寫抽象方法

11.一個類可以實現(xiàn)多個接口,使用implements用逗號隔開

5. 實現(xiàn)多個接口

在Java中,類和類之間是單繼承的,一個類只能有一個父類,即Java中不支持類的多繼承,但是一個類可以實現(xiàn)多個接口,使用implements用逗號隔開;可以用接口達到多繼承的效果,解決了Java中類不支持多繼承的問題。

下面的代碼展示了 Java 面向?qū)ο缶幊讨凶畛R姷挠梅? 一個類繼承一個父類, 同時也可以實現(xiàn)多種接口.

//動物類
class Animal {
    protected String name;
    public Animal(String name) {
        this.name = name;
    }
}
//提供一組接口, 分別表示 "會飛的", "會跑的", "會游泳的".
interface IFlying {
    void fly();
}
interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}
//貓, 是會跑的.
class Cat extends Animal implements IRunning {
    public Cat(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在用四條腿跑");
    }
}
//魚, 是會游的.
class Fish extends Animal implements ISwimming {
    public Fish(String name) {
        super(name);
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在用尾巴游泳");
    }
}
//青蛙, 既能跑, 又能游
class Frog extends Animal implements IRunning, ISwimming {
    public Frog(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在往前跳");
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在蹬腿游泳");
    }
}
//鴨子,可以飛、跑和游泳
class Duck extends Animal implements IRunning, ISwimming, IFlying {
    public Duck(String name) {
        super(name);
    }
    @Override
    public void fly() {
        System.out.println(this.name + "正在用翅膀飛");
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在用兩條腿跑");
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在漂在水上");
    }
}

繼承表達的含義是 is - a 語義, 而接口表達的含義是 具有 xxx 特性 .

貓是一種動物, 具有會跑的特性.

青蛙也是一種動物, 既能跑, 也能游泳

鴨子也是一種動物, 既能跑, 也能游, 還能飛

這樣的設(shè)計充分體現(xiàn)出多態(tài)的好處, 我們可以"忘記"類型; 有了接口之后, 類的使用者就不必關(guān)注具體類型, 而只關(guān)注某個類是否具備某種能力;通過接口可以讓其具備這種能力,進而通過接口引用實現(xiàn)多態(tài)。

比如下面的funRun方法

public static void funRun(IRunning running) {
        running.run();
}

在這個方法內(nèi)部, 我們并不關(guān)注到底是哪種動物, 只要參數(shù)是會跑的就行

public class Test {
    public static void funRun(IRunning running) {
        running.run();
    }
    public static void main(String[] args) {
        Cat cat = new Cat("小貓");
        funRun(cat);

        Frog frog = new Frog("小青蛙");
        funRun(frog);
    }
}

甚至參數(shù)可以不是 “動物”, 只要會跑!

class Robot implements IRunning {
    private String name;
    public Robot(String name) {
        this.name = name;
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在用輪子跑");
    }
}

public class Test {
    public static void funRun(IRunning running) {
        running.run();
    }

    public static void main(String[] args) {
        Robot robot = new Robot("機器人");
        funRun(robot);
    }
}

6. 接口間的繼承

在Java中,類和類之間是單繼承的,一個類可以實現(xiàn)多個接口,接口與接口之間可以多繼承。

用接口可以達到多繼承的目的。 接口可以繼承一個接口, 達到復(fù)用的效果. 使用 extends 關(guān)鍵字.

接口間的繼承相當于把多個接口合并在一起.

interface IFLying {
    void flying();
}
interface ISwimming {
    void swimming();
}
interface IRunning {
    void running();
}
//把IRunning,ISwimming,Iflying全部繼承到IThreehabitat上
interface IThreehabitat extends IFLying,IRunning,ISwimming{

}

class Animal {
    public String name;

    public Animal(String name) {
        this.name = name;
    }

}

class Duck extends Animal implements IThreehabitat {

    public Duck(String name) {
        super(name);
    }

    @Override
    public void flying() {
        System.out.println(name + "正在飛!");
    }

    @Override
    public void swimming() {
        System.out.println(name + "正在游泳!");
    }

    @Override
    public void running() {
        System.out.println(name + "正在跑!");
    }
}



public class Test {
    public static void func(IThreehabitat iThreehabitat) {
        iThreehabitat.flying();
        iThreehabitat.running();
        iThreehabitat.swimming();
    }

    public static void main(String[] args) {
        func(new Duck("小黃"));
    }
}

三. 抽象類和接口的區(qū)別

核心區(qū)別:

抽象類中可以包含普通方法和普通字段, 這樣的普通方法和字段可以被子類直接使用(不必重寫), 而接口中不能包含普通方法, 子類必須重寫所有的抽象方法

相同點:

  • 都不能被實例化。
  • 接口的實現(xiàn)類和抽象類的子類只有全部實現(xiàn)了接口或者抽象類中的抽象方法后才可以被實例化。

不同點:

  • 抽象類可以有構(gòu)造方法,接口中不能有構(gòu)造方法。
  • 接口只能定義抽象方法不能實現(xiàn)方法,抽象類既可以定義抽象方法,也可以實現(xiàn)方法。
  • 抽象類中可以包含靜態(tài)方法,接口中不能包含靜態(tài)方法。
  • 抽象類中可以有普通成員變量,接口中沒有普通成員變量,接口中的所有成員變量為public static final修飾的靜態(tài)常量。
  • 接口可以被多重實現(xiàn),抽象類只能被單一繼承。

到此這篇關(guān)于Java中抽象類和接口的用法詳解的文章就介紹到這了,更多相關(guān)Java抽象類 接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis-plus動態(tài)數(shù)據(jù)源讀寫分離方式

    mybatis-plus動態(tài)數(shù)據(jù)源讀寫分離方式

    在分布式項目開發(fā)中,動態(tài)數(shù)據(jù)源的配置與使用至關(guān)重要,通過創(chuàng)建DynamicDatasourceService,實現(xiàn)數(shù)據(jù)源的動態(tài)添加與調(diào)用,有效管理主從庫操作,減輕數(shù)據(jù)庫壓力,此外,通過配置類與@DS注解,實現(xiàn)了靈活的分庫查詢功能,為高效處理數(shù)據(jù)提供了強有力的支持
    2024-10-10
  • 關(guān)于JVM垃圾回收的java.lang.ref.Finalizer問題

    關(guān)于JVM垃圾回收的java.lang.ref.Finalizer問題

    這篇文章主要介紹了關(guān)于JVM垃圾回收的java.lang.ref.Finalizer問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java源碼解析之接口Collection

    Java源碼解析之接口Collection

    Collection是List、Queue和set的超集,它直接繼承于Iterable,也就是說所有的Collection集合類都支持foreach循環(huán).除此之外呢,Collection也是面向接口編程的典范,它可以在多種實現(xiàn)類間轉(zhuǎn)換,這就是面向?qū)ο缶幊痰膮柡χ?接下來就隨著小編一起去看看吧,需要的朋友可以參考下
    2021-05-05
  • java Tcp通信客戶端與服務(wù)器端實例

    java Tcp通信客戶端與服務(wù)器端實例

    這篇文章主要介紹了java Tcp通信客戶端與服務(wù)器端,結(jié)合完整實例形式詳細分析了java基于tcp的網(wǎng)絡(luò)通信客戶端與服務(wù)器端具體實現(xiàn)技巧,需要的朋友可以參考下
    2020-01-01
  • Java數(shù)據(jù)結(jié)構(gòu)中關(guān)于AVL樹的實現(xiàn)方法詳解

    Java數(shù)據(jù)結(jié)構(gòu)中關(guān)于AVL樹的實現(xiàn)方法詳解

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)中關(guān)于AVL樹的實現(xiàn)方法,AVL樹是高度平衡的二叉樹,它的特點是AVL樹中任何節(jié)點的兩個子樹的高度最大差別為1,本文主要給大家介紹了Java語言如何實現(xiàn)AVL樹,需要的朋友可以參考下
    2024-02-02
  • Java使用自動化部署工具Gradle中的任務(wù)設(shè)定教程

    Java使用自動化部署工具Gradle中的任務(wù)設(shè)定教程

    Grandle使用同樣運行于JVM上的Groovy語言編寫,本文會對此進行初步夠用的講解,接下來我們就一起來看一下Java使用自動化部署工具Gradle中的任務(wù)設(shè)定教程:
    2016-06-06
  • java?WebSocket?服務(wù)端實現(xiàn)代碼

    java?WebSocket?服務(wù)端實現(xiàn)代碼

    WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動發(fā)送信息給客戶端,這篇文章主要介紹了java?WebSocket?服務(wù)端代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • Java中StringBuilder字符串類型的操作方法及API整理

    Java中StringBuilder字符串類型的操作方法及API整理

    Java中的StringBuffer類繼承于AbstractStringBuilder,用來創(chuàng)建非線程安全的字符串類型對象,下面即是對Java中StringBuilder字符串類型的操作方法及API整理
    2016-05-05
  • MyBatis3.X復(fù)雜Sql查詢的語句

    MyBatis3.X復(fù)雜Sql查詢的語句

    這篇文章主要介紹了MyBatis3.X復(fù)雜Sql查詢的相關(guān)資料,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • 功能強大的TraceId?搭配?ELK使用詳解

    功能強大的TraceId?搭配?ELK使用詳解

    這篇文章主要為大家介紹了功能強大的TraceId?搭配?ELK使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09

最新評論

霸州市| 卢湾区| 资阳市| 印江| 瑞丽市| 小金县| 句容市| 阿拉善左旗| 高要市| 辽阳市| 昌都县| 河源市| 龙江县| 察雅县| 睢宁县| 尼木县| 阿荣旗| 红安县| 南昌市| 鲁甸县| 饶河县| 贵港市| 卢湾区| 衡东县| 措勤县| 庄河市| 绥宁县| 子长县| 新民市| 莲花县| 田林县| 仁布县| 和静县| 湘潭市| 兴宁市| 淳化县| 凉城县| 龙口市| 公安县| 梓潼县| 自贡市|