溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么掌握J(rèn)ava抽象類(lèi)與接口

發(fā)布時(shí)間:2023-05-08 11:54:14 來(lái)源:億速云 閱讀:125 作者:iii 欄目:編程語(yǔ)言

本文小編為大家詳細(xì)介紹“怎么掌握J(rèn)ava抽象類(lèi)與接口”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“怎么掌握J(rèn)ava抽象類(lèi)與接口”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

    abstract

    abstract介紹:可以用于修飾:類(lèi)(抽象類(lèi))、方法(抽象方法)

    abstract修飾類(lèi):

    ①此類(lèi)不能實(shí)例化(也就是不能創(chuàng)建這個(gè)類(lèi)的對(duì)象)

    ②雖然自己不能實(shí)例化,但是子類(lèi)會(huì)調(diào)用父類(lèi)的構(gòu)造器,所以抽象類(lèi)中一定有構(gòu)造器

    abstract修飾方法

    ①抽象方法只有方法的聲明沒(méi)有方法體,所在的類(lèi)一定是抽象類(lèi)。因?yàn)槿绻?lèi)不是抽象的,那這個(gè)類(lèi)就可以造對(duì)象,可以造對(duì)象就可以調(diào)用。反之抽象類(lèi)中可以沒(méi)有抽象方法。

    ② 若子類(lèi)重寫(xiě)了子類(lèi)重寫(xiě)了父類(lèi)所有的抽象方法才能實(shí)例化,如果沒(méi)有全部重寫(xiě),那么子類(lèi)也是抽象類(lèi),也需要用abstract修飾。

    ③abstract不能用來(lái)修飾私有方法、靜態(tài)方法、final關(guān)鍵字修飾的方法、final關(guān)鍵字修飾的類(lèi)。

    final明確不能繼承,但abstract需要子類(lèi)繼承所以不能用,因?yàn)槿绻麅蓚€(gè)方法都是static,不認(rèn)為兩個(gè)方法是重寫(xiě)或者覆蓋,所以abstract用來(lái)修飾靜態(tài)方法,就無(wú)法重寫(xiě)。

    抽象的應(yīng)用

    模板方法設(shè)計(jì)模式。在軟件開(kāi)發(fā)中實(shí)現(xiàn)一個(gè)算法時(shí),整體步驟很固定、通用,這些步驟在父類(lèi)中寫(xiě)好,某些易變的和不確定的部分可以抽象出來(lái)給子類(lèi)實(shí)現(xiàn)。

    抽象類(lèi)的匿名子類(lèi)對(duì)象
    public static void main(String[] args){
        //匿名對(duì)象
        eat(new son());
        //非匿名類(lèi)的非匿名對(duì)象
        son John=new son();
        eat(John);
        //匿名子類(lèi)對(duì)象
        father f=new father(){//抽象類(lèi)造對(duì)象必須要重寫(xiě)方法,了解看得懂就ok了。
            @Override
            public void work() {
            }
            @Override
            public void info(father i) {
            }
        };
    }
    //普通方法
    public static void eat(father f){
        System.out.println("吃飯");
    }
    //父類(lèi)
    public abstract static class father{
        String name;
        int age;
        public abstract void work();//抽象方法不能有方法體
        public abstract void info(father i);
    }
    //子類(lèi)
    public class son extends father{//繼承
        String name;
        int age;
        @Override
        public void work(){
            System.out.println("上學(xué)");
        }
        @Override
        public void info(father i) {
            System.out.println("name:"+i.name+" age:"+i.age);
        }
    }
    //接口的匿名對(duì)象
    非匿名的對(duì)象可以被多次調(diào)用,匿名的對(duì)象只能使用一次
    Computer com=new Computer();//創(chuàng)建了接口的非匿名實(shí)現(xiàn)類(lèi)(子類(lèi))的非匿名對(duì)象,類(lèi)和對(duì)象都是有名的
    Flash flash = new Flash();
    //2.創(chuàng)建了接口的非匿名實(shí)現(xiàn)類(lèi)的匿名對(duì)象,對(duì)象匿名了
    com.transferData(new Printer());
    //3創(chuàng)建了接口的匿名實(shí)現(xiàn)類(lèi)的非匿名對(duì)象,就是類(lèi)是匿名的,就不知道是接口中的哪個(gè)實(shí)現(xiàn)類(lèi),所以 需要重寫(xiě)方法進(jìn)行說(shuō)明
    USB  phone = new USB{
        public void start(){
            ...
        }
    };
    //4.創(chuàng)建了接口的匿名實(shí)現(xiàn)類(lèi)的匿名對(duì)象
    com.transferData(new USB(){
        public void start(){
            ...
        }  
        });

    final關(guān)鍵字

    final修飾類(lèi):此類(lèi)不能被其他類(lèi)所繼承,比如:String、System、StringBuffer

    final修飾方法:此方法不能再被重寫(xiě),比如:Object類(lèi)中的getClass()

    static final用來(lái)修飾屬性:全局常量

    final修飾變量:此時(shí)的變量就稱(chēng)為是一個(gè)常量

    final修飾屬性:可以考慮賦值的位置:顯式初始化,代碼塊中初始化、構(gòu)造器中初始化

    final修飾局部變量:尤其是用final修飾形參時(shí),表明此形參是一個(gè)常量,當(dāng)調(diào)用此方法時(shí),給常量形參賦實(shí)參,一旦賦值就只能在方法體內(nèi)使用此形參,但不能重新賦值

    接口

    接口使用Interface來(lái)定義,和類(lèi)是并列關(guān)系

    接口的定義以及接口中的成員:

    接口相關(guān)規(guī)則

    1.接口中所有方法都是抽象的。

    2.即使沒(méi)有顯式的將接口中的成員用public標(biāo)示,也是public訪(fǎng)問(wèn)類(lèi)型的

    3.接口中變量默認(rèn)用 public static final標(biāo)示,所以接口中定義的變量就是全 局靜態(tài)常量。

    4.可以定義一個(gè)新接口,用extends去繼承一個(gè)已有的接口

    5.可以定義一個(gè)類(lèi),用implements去實(shí)現(xiàn)一個(gè)接口中所有方法。

    6.可以定義一個(gè)抽象類(lèi),用implements去實(shí)現(xiàn)一個(gè)接口中部分方法。

    接口的特性

    1.接口不可以被實(shí)例化

    2.實(shí)現(xiàn)類(lèi)必須實(shí)現(xiàn)接口的所有方法

    3.實(shí)現(xiàn)類(lèi)可以實(shí)現(xiàn)多個(gè)接口

    4.接口中的變量都是靜態(tài)常量

    如果類(lèi)覆蓋了接口中所有的抽象方法,則可以創(chuàng)造實(shí)例;如果類(lèi)沒(méi)有覆蓋接口中所有的抽象方法,則該類(lèi)仍為抽象類(lèi)。Java類(lèi)可以實(shí)現(xiàn)多個(gè)接口——彌補(bǔ)了單繼承性的缺陷

    class AA extends BB implements CC,DD,EE

    接口和接口之間可以繼承,且可以多繼承。接口的使用體現(xiàn)了多態(tài)性。接口是一種規(guī)范,面向接口編程。

    抽象類(lèi)和接口的異同

    相同點(diǎn):不能實(shí)例化,都可以包含抽象方法

    不同點(diǎn):

    1. 把抽象類(lèi)和接口(java7、java8)的定義、內(nèi)部結(jié)構(gòu)解釋說(shuō)明

    2. 類(lèi):?jiǎn)卫^承性,接口:多繼承性。

    抽象類(lèi)與接口的練習(xí)

     abstract class Door {
        //開(kāi)門(mén)
        public abstract void openDoor();
        //關(guān)門(mén)
        public abstract void closeDoor();
    }
     interface Lock {
        public static final int num = 200;
        //開(kāi)鎖
        public abstract void openLock();
        //上鎖
        public abstract void closeLock();
    }
    class LockDoor extends Door implements Lock {
        public void openDoor() {
            System.out.println("開(kāi)門(mén)");
        }
        public void closeDoor() {
            System.out.println("關(guān)門(mén)");
        }
        public void openLock() {
            System.out.println("開(kāi)鎖");
        }
        public void closeLock() {
            System.out.println("上鎖");
        }
      }
    public class TestLockDoor {
        public static void main(String[] args) {
            LockDoor lockDoor = new LockDoor();
            lockDoor.openLock();
            lockDoor.openDoor();
            lockDoor.closeDoor();
            lockDoor.closeLock();
        }
    }

    接口的應(yīng)用

    兩種設(shè)計(jì)模式

    - 代理模式

    代理設(shè)計(jì)就是為其他對(duì)象提供一張代理以控制對(duì)這個(gè)對(duì)象的訪(fǎng)問(wèn)

    應(yīng)用場(chǎng)景:安全代理、遠(yuǎn)程代理、延遲加載

    分類(lèi):靜態(tài)代理、動(dòng)態(tài)代理

    - 工廠(chǎng)模式

    實(shí)現(xiàn)創(chuàng)建者和調(diào)用者的分離

    interface A{
        int x=0;
    }
    class B{
        int x=1;
    }
    class C extends B implements A{
        public void pX(){
            System.out.println(x);
        }
        public static void main(String[] args){
            new C().pX();
        }
    }
    //問(wèn)題:編譯期不知道是要輸出哪個(gè)x
    System.out.println(super.x);//這個(gè)調(diào)用的是父類(lèi)中的
    System.out.println(A.x);//這個(gè)調(diào)用的是接口中的

    java8中接口新特性

    JDK8:除了全局常量和抽象方法,還可以定義靜態(tài)方法和默認(rèn)方法(default關(guān)鍵字修飾)

    public interface CompareA{  
      public static void method1(){
      //靜態(tài)方法        
      System.out.println("CompareA:北京");   
       }   
        public default void method2(){
        //默認(rèn)方法        
        System.out.println("CompareA:上海");   
         }
      }

    接口中定義的靜態(tài)方法只能通過(guò)接口來(lái)調(diào)用,接口.方法。

    通過(guò)實(shí)現(xiàn)類(lèi)的對(duì)象,可以調(diào)用接口中的默認(rèn)方法,對(duì)象.方法。

    如果實(shí)現(xiàn)類(lèi)重寫(xiě)了接口中的默認(rèn)方法,調(diào)用時(shí)仍然調(diào)用的是重寫(xiě)以后的方法

    如果子類(lèi)(或?qū)崿F(xiàn)類(lèi))繼承的父類(lèi)和實(shí)現(xiàn)的接口中聲明了同名同參數(shù)的方法,子類(lèi)在沒(méi)有重寫(xiě)此方法的情況下調(diào)用的是父類(lèi)中的方法——類(lèi)優(yōu)先原則

    如果實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)了多個(gè)接口,而這個(gè)多個(gè)接口中定義了同名同參數(shù)的默認(rèn)方法,在實(shí)現(xiàn)類(lèi)沒(méi)有重寫(xiě)方法的情況下會(huì)報(bào)”接口沖突“錯(cuò)誤,此時(shí)需要重寫(xiě)。

    如何在子類(lèi)(或者實(shí)現(xiàn)類(lèi))調(diào)用父類(lèi)、接口中被重寫(xiě)的方法? 接口.super.方法。

    內(nèi)部類(lèi)

    需要關(guān)注的問(wèn)題:如何實(shí)例化成員內(nèi)部類(lèi)的對(duì)象:外部類(lèi)Person,靜態(tài)內(nèi)部類(lèi)Brain,非靜態(tài)內(nèi)部類(lèi)Lungs,靜態(tài)成員內(nèi)部類(lèi):new 外部類(lèi).內(nèi)部類(lèi)()

    Person.Brain brain=new Person.Brain();

    非靜態(tài)成員內(nèi)部類(lèi):先造對(duì)象,對(duì)象.new 內(nèi)部類(lèi)()

    Person p=new Person();
    p.Lungs lungs=p.new Lungs();

    如何在成員內(nèi)部類(lèi)中區(qū)分調(diào)用外部類(lèi)的結(jié)構(gòu)

    形參直接調(diào),所在類(lèi)的用this.結(jié)構(gòu),外部類(lèi)的用外部類(lèi).this.結(jié)構(gòu)

    成員內(nèi)部類(lèi)和局部?jī)?nèi)部類(lèi)在編譯以后都會(huì)生成字節(jié)碼文件

    成員內(nèi)部類(lèi):外部類(lèi).內(nèi)部類(lèi)名.class

    局部?jī)?nèi)部類(lèi):外部類(lèi).數(shù)字 內(nèi)部類(lèi)名.class

    在局部?jī)?nèi)部類(lèi)的方法中,如果調(diào)用局部?jī)?nèi)部類(lèi)所在的方法中的局部變量,該局部變量必須用final關(guān)鍵字修飾(JAVA8之后可以不寫(xiě)出來(lái),但仍然還是final的)

    public void Person(){
        int num=10;
        class AA{//局部?jī)?nèi)部類(lèi)
            public void show(){//局部?jī)?nèi)部類(lèi)的方法
                num=20;//試圖修改會(huì)報(bào)錯(cuò)
                System.out.println(num);//調(diào)用局部?jī)?nèi)部類(lèi)所在的方法中的局部變量
            }
        }
    }

    開(kāi)發(fā)中局部?jī)?nèi)部類(lèi)的使用

    常用的局部?jī)?nèi)部類(lèi):

    //方式一
    public Comparable getCompareble(){
        class MyComparable implements Comparable{//局部?jī)?nèi)部類(lèi)
    
            public int compareTo(Object o){
                return 0;
            }
        }
        return new MyComparable();
    }
    //方式二
    public Comparable getCompareble(){
        return new Comparable(){
    
            public int CompareTo(Object o){
                return 0;
            }
        };
    }

    Java允許將一個(gè)類(lèi)A聲明在另一個(gè)類(lèi)B中,A為內(nèi)部類(lèi),B為外部類(lèi)

    內(nèi)部類(lèi)的分類(lèi):成員內(nèi)部類(lèi)、局部?jī)?nèi)部類(lèi)(方法內(nèi),代碼塊內(nèi),構(gòu)造器內(nèi))

    成員內(nèi)部類(lèi)

    作為外部類(lèi)的成員:可以調(diào)用外部類(lèi)的結(jié)構(gòu),可以被static修飾

    作為一個(gè)類(lèi):可以定義屬性、方法、構(gòu)造器,可以用final、abstract修飾,可以被繼承

    this.name//內(nèi)部類(lèi)的屬性

    Person.this.name//外部類(lèi)的屬性

    讀到這里,這篇“怎么掌握J(rèn)ava抽象類(lèi)與接口”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI