JAVA之從入門到放棄(三)

訪問(wèn)修飾符 (訪問(wèn)控制)

作用:控制當(dāng)前代碼的可見(jiàn)范圍 目的:保護(hù)程序的合法性,安全性,健壯性
屬性的封裝:屬性私有化,方法公開(kāi)化

public(公開(kāi)的):任意位置都可以訪問(wèn),權(quán)限最大
protected(保護(hù)的):一般存在父級(jí)代碼中,當(dāng)前類/同包類/子類 可見(jiàn)
默認(rèn)的:默認(rèn)訪問(wèn)修飾符是不建議的 當(dāng)前類/同包類 可見(jiàn)
private(私有的):權(quán)限最小 當(dāng)前類 可見(jiàn)

final

final代表的是最終的意思,可以修飾類、屬性、方法

  • 修飾屬性:final修飾符變量要么在聲明時(shí)初始化,要么在構(gòu)造方法中初始化
  • 修飾方法:final修飾的方法不可以被重寫,所以存在于父級(jí)代碼中
  • 修飾類:final修飾的類不可以被繼承
//final測(cè)試演示類
public class FinalDemo {
    private final int a; //final修飾符變量要么在聲明時(shí)初始化
    FinalDemo() {
        a = 10; //final修飾符變量要么在構(gòu)造方法中初始化
    }

    void show() {
//        a = 10; //final修飾符變量不能再普通方法中初始化
    }
}

final class Aoo { //final修飾的類不可以被繼承
    public final void test() { //final修飾的方法不可以被重寫

    }
}

class Boo/* extends Aoo*/ {
//    public void test() {   //不可以重寫
//
//    }
}
static (靜態(tài)變量)
靜態(tài)資源:

如:
每個(gè)學(xué)生的杯子屬于對(duì)象嗎?屬于,屬于個(gè)人的
飲水機(jī)屬于對(duì)象嗎?不屬于,但可以被對(duì)象共享。----->靜態(tài)資源

  • 實(shí)例變量:屬于對(duì)象的!特點(diǎn):有多少個(gè)對(duì)象就有多少份,在堆中
    • 實(shí)例變量的訪問(wèn):通過(guò)對(duì)象名打點(diǎn)的形式訪問(wèn)
  • 靜態(tài)變量:屬于類的!特點(diǎn):有且只有一份,被所有對(duì)象共享,在方法區(qū)中存儲(chǔ)
    • 靜態(tài)變量的訪問(wèn):通過(guò)類名打點(diǎn)的形式訪問(wèn)
  • 靜態(tài)變量適用性:當(dāng)一份資源需要被多個(gè)對(duì)象共享時(shí)可以做成靜態(tài)資源
方法區(qū)特點(diǎn):一個(gè)類應(yīng)該有一份.class字節(jié)碼文件,當(dāng)類被首次使用時(shí),該類的.class 字節(jié)碼文件會(huì)被加載到方法區(qū)中,加載且只加載一次

JVM分配空間:棧區(qū),堆區(qū),方法區(qū)
棧區(qū):放局部變量的區(qū)域
堆區(qū):放對(duì)象的區(qū)域
方法區(qū):用來(lái)加載.class字節(jié)碼文件(類中的靜態(tài)變量,類中的方法(構(gòu)造方法/靜態(tài)方法/普通方法))

class Coo {
    public int a;//實(shí)例變量:屬于對(duì)象的,有多個(gè)對(duì)象有多少份
    public static int b;//靜態(tài)變量:屬于類的,只有一份被所有對(duì)象共享
    Coo() {
        a++;
        b++;
    }
    void show() {//普通方法
        this.a = 0;//訪問(wèn)類實(shí)例成員默認(rèn)有個(gè)this的寫法
        Coo.b = 0;//訪問(wèn)類靜態(tài)成員默認(rèn)有個(gè)類名點(diǎn)的寫法
        System.out.println("實(shí)例變量a的值:" + a + ",靜態(tài)變量b的值:" + b);
    }
    static void show2() {//靜態(tài)方法中:無(wú)法使用this
//        this.a = 1;  普通實(shí)例成員不可直接在static修飾的方法中調(diào)用
//           this.show();普通方法不可直接在static修飾的方法中調(diào)用
        Coo.b = 1;//靜態(tài)方法可直接訪問(wèn)靜態(tài)的內(nèi)容.
    }
}
static (靜態(tài)方法)

用static修飾的方法稱之為靜態(tài)方法

  • 靜態(tài)方法屬于類,通過(guò)類名打點(diǎn)調(diào)用
  • 靜態(tài)方法存儲(chǔ)在方法區(qū)中
  • 靜態(tài)方法時(shí)沒(méi)有隱式this傳遞的,所以靜態(tài)方法是無(wú)法訪問(wèn)類中實(shí)例成員(普通實(shí)例變量,普通方法)
  • 靜態(tài)方法的適用性:靜態(tài)方法一般存在于工具類中,對(duì)于外部來(lái)講調(diào)用方便,只需要類名點(diǎn)的形式就可以調(diào)用該方法
class Coo {
    private int a; //實(shí)例變量:屬于對(duì)象的,有多少個(gè)對(duì)象有多少份
    public static int b; //靜態(tài)變量:屬于類的,有且只有一份被所有對(duì)象共享
    Coo() {
        a ++;
        b ++;
    }

    void show() {   //普通方法
        this.a = 0; //訪問(wèn)類實(shí)例成員默認(rèn)有個(gè)this
        Coo.b = 0;  //訪問(wèn)靜態(tài)成員默認(rèn)有個(gè)類名點(diǎn)的寫法
        System.out.println("實(shí)例變量a的值:" + a + "靜態(tài)變量b的值:" + b);
    }
    static void show2() { // 靜態(tài)方法中:無(wú)法使用this
//        a = 0;        普通實(shí)例成員不可以在static修飾的方法中調(diào)用
//        this.show();  普通方法不可以在static修飾的方法中調(diào)用
        Coo.b = 2;     //靜態(tài)方法可以直接訪問(wèn)類的靜態(tài)內(nèi)容
    }
}
static (靜態(tài)代碼塊)
  • 用static修飾的代碼塊稱之為靜態(tài)代碼塊
  • 靜態(tài)代碼塊屬于類,當(dāng)類被首次加載時(shí),會(huì)自動(dòng)調(diào)用靜態(tài)代碼塊且只調(diào)用一次
  • 靜態(tài)代碼塊適用性:當(dāng)成員都是靜態(tài)成員時(shí),也無(wú)需外部創(chuàng)建對(duì)象,類中靜態(tài)成員初始化賦值的功能,可以交給靜態(tài)代碼塊來(lái)完成
/*測(cè)試靜態(tài)代碼塊的類*/
public class StaticDemo2 {
    public static void main(String[] args) {
//        Doo doo1 = new Doo();
//        Doo doo2 = new Doo();
        Doo doo3 = new Doo();
//        Doo.a = 2; //訪問(wèn)類中的靜態(tài)成員 也叫使用類,如果是首次使用則會(huì)加載
    }
}

class Doo {
    public static int a = 2;
    Doo() { //創(chuàng)建多少個(gè)對(duì)象 則執(zhí)行多少次   構(gòu)造方法的作用:創(chuàng)建對(duì)象時(shí)可以為對(duì)象初始化數(shù)據(jù)
        System.out.println("Doo類的構(gòu)造方法執(zhí)行了");
    }
    static {    //靜態(tài)代碼塊:類被首次加載時(shí)執(zhí)行,且只加載一次  靜態(tài)代碼塊的作用:一般用于為靜態(tài)成員初始化使用的語(yǔ)法
        System.out.println("Doo類被加載了。。我執(zhí)行了。。");
    }
}
常量

用static final修飾的屬性則是常量,常量結(jié)合static和final的特性
特性:常量可以通過(guò)類名打點(diǎn)形式訪問(wèn),不能二次修改且聲明時(shí)需要初始化
常量命名:要求純大寫,多個(gè)單詞之間用下劃線隔開(kāi)
常量的適用性:當(dāng)有一份數(shù)據(jù),確定后幾乎不會(huì)發(fā)生改變的,也不會(huì)頻繁修改得,那么可以作為常量來(lái)表示,常量一般也可以用于表示一些固定狀態(tài)的使用

/*常量的使用演示類*/
public class StaticFinalDemo {
    public static void main(String[] args) {
//        System.out.println(Eoo.a);
//        Eoo e = new Eoo();
//        System.out.println(e.b);

        /*1.先將Eoo類字節(jié)碼文件加載到方法區(qū)
        * 2.輸出靜態(tài)變量a的值*/
        System.out.println(Eoo.a);

       /*在編譯期間使用常量,本質(zhì)上就是將常量的值進(jìn)行訪問(wèn)(不會(huì)執(zhí)行static代碼塊)*/
        System.out.println(Eoo.C);
    }
}

class Eoo {
    public static int a;            //靜態(tài)變量
    public final int b = 1;         //final修飾的變量
    public static final int C = 100;//常量
    static {
        System.out.println("靜態(tài)代碼塊執(zhí)行了、、、、");
    }
}
抽象方法(半成品)
  • 用abstract修飾的方法稱之為抽象方法
  • 抽象方法需要存在于抽象類
  • 抽象方法不能有方法體
  • 抽象方法必須要子類重寫
抽象類
  • 用abstract修飾的類稱之為抽象類
  • 抽象類不能被實(shí)例化對(duì)象
  • 抽象類只是能在普通類的基礎(chǔ)上可以放抽象內(nèi)容而已
  • 抽象類一定要有子類實(shí)現(xiàn)的,否則抽象類沒(méi)有意義

抽象方法的意義:
1)遵循面向?qū)ο笤O(shè)計(jì)原則,如果父類中提供的方法子類都不能用是不是需要重寫?
如果做成普通方法,子類是不是可以重寫 也可以不重寫?
目的:為了約束子類必須重寫,不重寫代碼報(bào)錯(cuò)
2)子類都重寫了,父類的抽象方法還有存在的意義嗎?
目的:父類中存在的抽象方法的意義是為了向上造型,調(diào)用父類執(zhí)行子類

內(nèi)部類 (應(yīng)用率不高)

內(nèi)部類:類中套個(gè)類,類結(jié)構(gòu)中的類稱之為內(nèi)部類

  • 內(nèi)部類不具備可見(jiàn)性
  • 內(nèi)部類共享外部類成員,可以直接訪問(wèn)。但如果外部類成員命名與內(nèi)部類成員命名沖突時(shí),那么我們可以明確寫外部類名.this.xx即可
class Aoo { //外部類
      class Boo { //內(nèi)部類
      }
}
匿名內(nèi)部類 (應(yīng)用率高)

匿名內(nèi)部類:沒(méi)有名字的內(nèi)部類稱之為匿名內(nèi)部類
適用性:當(dāng)一個(gè)子類僅僅只是為了實(shí)現(xiàn)重寫父類中的某個(gè)功能時(shí),而其他地方根本不用該子類,那么我們可以使用匿名內(nèi)部類的方式,目的:讓面相實(shí)現(xiàn)開(kāi)發(fā),而不關(guān)心語(yǔ)法,更關(guān)心的是邏輯如何實(shí)現(xiàn)

  • 匿名內(nèi)部類的使用:只會(huì)存在于只是重寫父類方法的情況才會(huì)使用
  • 匿名內(nèi)部類訪問(wèn)外部類成員:對(duì)于
        //1.創(chuàng)建一個(gè)匿名內(nèi)部類,花括號(hào)就是匿名子類的類體
        //2.運(yùn)行時(shí)創(chuàng)建的子類對(duì)象賦值給sub
        //3.通過(guò)sub調(diào)用重寫的show方法
        SupperDemo sub = new SupperDemo() {
            @Override
            void show() {
//                sub.a = 20; // 匿名內(nèi)部類訪問(wèn)外部類成員 會(huì)自動(dòng)修飾為final, a不可二次修改
                System.out.println(a); //可以訪問(wèn)
                System.out.println("匿名內(nèi)部類重寫了父類中的show方法");
            }
        };
        sub.show();

問(wèn):內(nèi)部類有沒(méi)有獨(dú)立的.class字節(jié)碼文件?
答:無(wú)論是成員內(nèi)部類還是匿名內(nèi)部類都有.class字節(jié)碼文件


數(shù)組擴(kuò)容

Arrays.copy

        int[] array = {}; //為array數(shù)組創(chuàng)建了一個(gè)數(shù)組對(duì)象, 數(shù)組長(zhǎng)度為0
        int a = 100;
        //copyOf: 1.要擴(kuò)容的數(shù)組對(duì)象 2.基于原數(shù)組長(zhǎng)度的基礎(chǔ)上 + 或 - 要擴(kuò)容或縮容的容量
        array = Arrays.copyOf(array, array.length + 1);
        System.out.println("擴(kuò)容后" + array.length);
        array[array.length - 1] = a;
        System.out.println("存數(shù)后" + Arrays.toString(array));

System.arrayCopy

        int[] a = {50, 60, 70, 80};
        int[] b = {0, 0, 0, 0};
        /*arrayCopy的5個(gè)參數(shù)
        * 1.要拷貝的原數(shù)組
        * 2.從原數(shù)組哪個(gè)下標(biāo)開(kāi)始拷貝
        * 3.要拷貝到的目標(biāo)數(shù)組
        * 4.從目標(biāo)數(shù)組哪個(gè)下標(biāo)開(kāi)始裝載
        * 5.拷貝的數(shù)量, 目標(biāo)數(shù)組長(zhǎng)度 - 目標(biāo)數(shù)組裝載的下標(biāo)
        (注意:拷貝的數(shù)量不能超過(guò)目標(biāo)數(shù)組容納的范圍)*/
        System.arraycopy(a, 1, b, 1, a.length - 1);
接口

定義:接口是一組行為的規(guī)范,接口并不關(guān)心多個(gè)類之間是否是一種的關(guān)系,只關(guān)心這些類的行為是否一樣,一個(gè)類可以實(shí)現(xiàn)多個(gè)接口,一般一個(gè)接口只代表一個(gè)行為,不要做大而全的接口,要做小而精的接口

  • 接口是一種數(shù)據(jù)類型,是引用類型,同樣也有.class字節(jié)碼文件
  • 接口使用interface關(guān)鍵字來(lái)定義
  • 接口中只能放常量和和抽象方法
  • 實(shí)現(xiàn)類必須重寫接口中的所有方法 使用implement戳上接口名來(lái)實(shí)現(xiàn)
  • 實(shí)現(xiàn)類又要繼承類 又要實(shí)現(xiàn)接口的方法 那么先繼承后實(shí)現(xiàn)接口方法
  • 實(shí)現(xiàn)類可以實(shí)現(xiàn)多個(gè)接口,實(shí)現(xiàn)時(shí)接口名之間用逗號(hào)隔開(kāi)
  • 接口之間是可以繼承的
抽象類和接口的區(qū)別
  • 語(yǔ)法區(qū)別:
    • 抽象類可以有構(gòu)造方法 | 接口沒(méi)有
    • 抽象類可以有普通變量、方法/抽象方法 | 接口只能放常量,抽象方法1.8支持靜態(tài)方法
    • 抽象類成員可選擇不同訪問(wèn)修飾符 | 接口默認(rèn)都是public
    • 一個(gè)類只能繼承類 | 接口可以繼承多個(gè)接口
  • 設(shè)計(jì)使用區(qū)別
    • 繼承:多個(gè)類之間存在共性的屬性和行為時(shí),且這些類在概念上是一種的關(guān)系,可以用繼承來(lái)復(fù)用優(yōu)化代碼
      • 繼承好處:復(fù)用代碼(屬性),可以向上造型,調(diào)父執(zhí)行子
      • 繼承缺點(diǎn):耦合度高,牽一發(fā)而動(dòng)全身
    • 接口:多個(gè)類之間存在共有行為時(shí),不管這些類概念上是否是一種的關(guān)系,可以用接口來(lái)代表這些類的行為
      • 接口好處:代表行為,可以向上造型,調(diào)用父執(zhí)行,接口是可以多實(shí)現(xiàn)
      • 高內(nèi)聚:一個(gè)類或一個(gè)方法盡可能只干相關(guān)的事情 低耦合:類與類之間的關(guān)系盡量松散
多態(tài)

在程序中多態(tài)指的是,一個(gè)父類下的行為子類有不同的實(shí)現(xiàn)

向上造型:引用類型中的自動(dòng)類型轉(zhuǎn)換

能夠向上造型的語(yǔ)法:實(shí)現(xiàn)繼承關(guān)系 聲明父 new子 | 實(shí)現(xiàn)關(guān)系 聲明接口 new 實(shí)現(xiàn)類

向下轉(zhuǎn)型:引用類型中的強(qiáng)制類型轉(zhuǎn)換

引用類型中能否強(qiáng)制轉(zhuǎn)換成功,具體參考以下兩個(gè)條件

  • 條件1:要強(qiáng)轉(zhuǎn)引用類型變量中的對(duì)象,就是要轉(zhuǎn)換的這個(gè)類型
  • 條件2:要強(qiáng)轉(zhuǎn)引用類型變量中的對(duì)象,實(shí)現(xiàn)了要轉(zhuǎn)換的這個(gè)接口
    強(qiáng)轉(zhuǎn)時(shí)建議用instanceof判斷是否強(qiáng)轉(zhuǎn)成功
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容