溫馨提示×

溫馨提示×

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

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

Java中類與對象的相關(guān)知識點(diǎn)有哪些

發(fā)布時間:2021-11-05 17:47:47 來源:億速云 閱讀:154 作者:柒染 欄目:開發(fā)技術(shù)

這篇文章給大家介紹Java中類與對象的相關(guān)知識點(diǎn)有哪些,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

    一、面向過程與面向?qū)ο蟮睦斫?/h3>

    C語言是面向過程的,關(guān)注的是過程,分析出求解問題的步驟,通過函數(shù)調(diào)用逐步解決問題。

    JAVA是基于面向?qū)ο蟮模P(guān)注的是對象,將一件事情拆分成不同的對象,靠對象之間的交互完成。

    面向過程注重的是過程,指的是在整個過程中所涉及的行為。

    面向?qū)ο笞⒅氐氖菍ο?,也就是參與過程所涉及到的主體。是通過邏輯將一個個功能實(shí)現(xiàn)連接起來。

    面向過程: 1.把冰箱打開 2. 把東西放入 3. 冰箱關(guān)起來 面向?qū)ο螅?打開冰箱,儲存,關(guān)閉都是對冰箱的操作,是冰箱被動的行為。冰箱就是一個對象,所以只要操作冰箱所具備的功能,都要定義在冰箱中(即類)。

    二、類與對象的理解與認(rèn)識

    類就是一類對象的統(tǒng)稱。對象就是這一類具體化的一個實(shí)例。類可以比喻為一個一個的模板,里面可能會含有許多屬性或者功能。而按照模板實(shí)例化產(chǎn)生的叫對象。一個模板能夠?qū)嵗鄠€對象。

    聲明一個類就是創(chuàng)建一個新的數(shù)據(jù)類型,而類在 Java 中屬于引用類型, Java 使用關(guān)鍵字 class 來聲明類。下面是聲明類的定義:

    // 創(chuàng)建類
    class <class_name>{  
        field;//成員屬性
        method;//成員方法
    }
    // 實(shí)例化對象
    <class_name> <對象名> = new <class_name>();

    class為定義類的關(guān)鍵字,ClassName為類的名字,{}中為類的主體。

    類中的元素稱為:成員屬性。類中的函數(shù)稱為:成員方法。

    示例:這里就聲明了一個類

    class Person {
        public int age;//成員屬性 實(shí)例變量
        public String name;
        public String sex;
        public void eat() {//成員方法
           System.out.println("吃飯!");  
       }
        public void sleep() {
           System.out.println("睡覺!");  
       }
    }
    class Person {
        public int age;//成員屬性 實(shí)例變量
        public String name;
        public String sex;
            public void eat() {//成員方法
           System.out.println("吃飯!");  
       }
        public void sleep() {
           System.out.println("睡覺!");  
       }
    }
    public class Main{
     public static void main(String[] args) {
            Person person = new Person();//通過new實(shí)例化對象
            person.eat();//成員方法調(diào)用需要通過對象的引用調(diào)用
            person.sleep();
            //產(chǎn)生對象     實(shí)例化對象
            Person person2 = new Person();
            Person person3 = new Person();
     }
    }

    輸出結(jié)果為:

    吃飯!
    睡覺!

    注意事項(xiàng):

    1. new 關(guān)鍵字用于創(chuàng)建一個對象的實(shí)例。

    2. 使用 . 來訪問對象中的屬性和方法。

    3. 同一個類可以創(chuàng)建多個實(shí)例。

    三、類的成員

    類的成員可以包含以下:字段、方法、代碼塊、內(nèi)部類和接口等。此處重點(diǎn)介紹前面三個。

    1.字段/屬性/成員變量

    在類中、而方法外部定義的變量稱為 “字段” 或 “屬性” 或 “成員變量”(三種稱呼都可以, 一般不會嚴(yán)格區(qū)分)

    class Person {
        public String name;   // 字段
        public int age; }
    class Test {
        public static void main(String[] args) { 
        Person person = new Person();
        System.out.println(person.name);
        System.out.println(person.age);
       }
    }
    // 執(zhí)行結(jié)果
    null
    0

    注意事項(xiàng):

    • 使用 . 訪問對象的字段。

    • “訪問” 既包含讀, 也包含寫.

    • 對于一個對象的字段如果沒有顯式設(shè)置初始值, 那么會被設(shè)置一個默認(rèn)的初值。

    默認(rèn)值規(guī)則
    對于各種數(shù)字類型, 默認(rèn)值為 0.
    對于 boolean 類型, 默認(rèn)值為 false.
    對于引用類型(String, Array, 以及自定制類), 默認(rèn)值為 null

    2.對null的基本認(rèn)識

    null 在 Java 中為 “空引用”, 表示不引用任何對象. 類似于 C 語言中的空指針. 如果對 null 進(jìn)行 . 操作就會引發(fā)異常。

    class Person {
        public String name;
        public int age; }
    class Test {
        public static void main(String[] args) {
            Person person = new Person();
            System.out.println(person.name.length());   // 獲取字符串長度
       }
    }
    // 執(zhí)行結(jié)果
    Exception in thread "main" java.lang.NullPointerException  //空指針異常
            at Test.main(Test.java:9)

    字段就地初始化:

    雖然此時我們都不想屬性都為默認(rèn)值而需要就地初始化,但是后面我們會講到盡量不要用字段的就地初始化,否則程序會顯得非常死板。

    class Person {
        public String name = "張三";
            public int age = 18; 
    }
    class Test {
        public static void main(String[] args) {
            Person person = new Person();
            System.out.println(person.name);
            System.out.println(person.age);
       }
    }
    // 執(zhí)行結(jié)果
    張三
    18

    引用中需要注意的地方:

    1.下面這段代碼指的是person2這個引用指向person引用指向的對象。

    public static void main(String[] args) {
            Person person = new Person();
            Person person2 = person;
        }

    2.一個引用無法指向多個對象,即使多次指向?qū)ο蠛?,最后指向的只能是最后一次指向的對象?/p>

    3.我們知道了局部變量是在棧上開辟內(nèi)存的,而它存儲的是地址,也稱為引用。那么引用一定是在棧上嗎?? 答案是否定的,看下面的代碼:

    class Person {
        public String name ;
        public int age ;
    }
    public class TestDemo {
        Person person = new Person();
    
        public static void main(String[] args) {
            TestDemo testDemo = new TestDemo();
        }
    }

    內(nèi)存布局:

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    3.方法 (method)

    用于描述一個對象的具體行為叫做方法。

    class Person {
        public int age = 18;
        public String name = "張三";
        public void show() { //show方法
       System.out.println("我叫" + name + ", 今年" + age + "歲");
       }
    }
    class Test {
        public static void main(String[] args) {
            Person person = new Person();
            person.show();
       }
    }
    // 執(zhí)行結(jié)果
    我叫張三, 今年18歲

    這樣的 show 方法是和 person 實(shí)例相關(guān)聯(lián)的,如果創(chuàng)建了其他實(shí)例,并且講類當(dāng)中的屬性重新賦值,那么 show 的行為就會發(fā)生變化。

    Person person2 = new Person();
    person2.name = "李四";
    person2.age = 20;
    person2.show();
    // 執(zhí)行結(jié)果
    我叫李四, 今年20歲

    4.static 關(guān)鍵字

    static關(guān)鍵字的作用:

    1. 修飾屬性 (內(nèi)存開辟在方法區(qū)中)

    2. 修飾方法 (只有調(diào)用方法時才在棧中開辟內(nèi)存)

    3. 代碼塊(本課件中會介紹)

    4. 修飾類(后面講內(nèi)部類會講到)

    1)修飾屬性:Java靜態(tài)屬性和類相關(guān), 和具體的實(shí)例無關(guān)。換句話說, 同一個類的不同實(shí)例共用同一個靜態(tài)屬性。

    class TestDemo{
        public int a;
        public static int count; }
    public class Main{
     public static void main(String[] args) {
            TestDemo t1 = new TestDemo();
            t1.a++;
            TestDemo.count++;
            System.out.println(t1.a);
            System.out.println(TestDemo.count);
            System.out.println("============");
            TestDemo t2 = new TestDemo();
            t2.a++;
            TestDemo.count++;
            System.out.println(t2.a);
            System.out.println(TestDemo.count);
       }
    }

    輸出結(jié)果:

    1
    1
    ============
    1
    2

    若需要調(diào)用類當(dāng)中的有static的屬性,則只需要類名.屬性 即可調(diào)用,而不能對象名.屬性 來調(diào)用,否則編譯器會報(bào)警告。

    被static修飾的成員變量的內(nèi)存在方法區(qū)中開辟,因?yàn)樗粚儆趯ο笠虼瞬辉诙焉祥_辟內(nèi)存;而在方法區(qū)中開辟內(nèi)存開辟且僅開辟一次。

    下圖體現(xiàn)出對象、類、屬性(實(shí)例成員變量、靜態(tài)成員變量)之間的關(guān)系。

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    2) 修飾方法

    如果在任何方法上應(yīng)用 static 關(guān)鍵字,此方法稱為靜態(tài)方法。

    1. 靜態(tài)方法屬于類,而不屬于類的對象。

    2. 可以直接調(diào)用靜態(tài)方法,而無需創(chuàng)建類的實(shí)例。

    3. 靜態(tài)方法可以訪問靜態(tài)數(shù)據(jù)成員,并可以更改靜態(tài)數(shù)據(jù)成員的值。

    class TestDemo{
        public int a;
        public static int count;
        
        public static void change() {
            count = 100;
            //a = 10; error 不可以訪問非靜態(tài)數(shù)據(jù)成員
       }
    }
    public class Main{
        public static void main(String[] args) {
            TestDemo.change();//無需創(chuàng)建實(shí)例對象 就可以調(diào)用
            System.out.println(TestDemo.count);   
       }
    }

    輸出結(jié)果:

    100

    注意事項(xiàng):靜態(tài)方法和實(shí)例無關(guān), 而是和類相關(guān). 因此這導(dǎo)致了兩個情況:

    1. 靜態(tài)方法不能直接使用非靜態(tài)數(shù)據(jù)成員或調(diào)用非靜態(tài)方法(非靜態(tài)數(shù)據(jù)成員和方法都是和實(shí)例相關(guān)的).

    2. this和super兩個關(guān)鍵字不能在靜態(tài)上下文中使用(this 是當(dāng)前實(shí)例的引用, super是當(dāng)前實(shí)例父類實(shí)例的引用, 也是和當(dāng)前實(shí)例相關(guān))

    3. 因?yàn)閙ain方法為static方法,因此只能實(shí)例化其他類后才能調(diào)用其他類中的實(shí)例成員變量或?qū)嵗蓡T方法,當(dāng)然main方法也可以直接用類名去調(diào)用其他類中的靜態(tài)成員變量或靜態(tài)方法。

    4. 靜態(tài)變量是屬于類的,因此在方法中不能定義被static修飾的靜態(tài)方法(包括普通方法和靜態(tài)方法),但是可以初始化或者使用。

    5. 普通方法中可以調(diào)用靜態(tài)方法,而靜態(tài)方法中不能調(diào)用普通方法,卻又可以調(diào)用其它的靜態(tài)方法。

    觀察以下代碼及理解其內(nèi)存布局:

    class Person {
        public int age;//實(shí)例變量   存放在對象內(nèi)
        public String name;//實(shí)例變量
        public String sex;//實(shí)例變量
        public static int count;//類變量也叫靜態(tài)變量,編譯時已經(jīng)產(chǎn)生,屬于類本身,且只有一份。存放在方法區(qū)
        public final int SIZE = 10;//被final修飾的叫常量,也屬于對象。 被final修飾,后續(xù)不可更改
        public static final int  COUNT = 99;//靜態(tài)的常量,屬于類本身,只有一份 被final修飾,后續(xù)不可更
    改
        //實(shí)例成員函數(shù)
        public void eat() {
           int a = 10;//局部變量
           System.out.println("eat()!");  
       }
        //實(shí)例成員函數(shù)
        public void sleep() {
           System.out.println("sleep()!");  
       }
        //靜態(tài)成員函數(shù)
         public static void staticTest(){
             //不能訪問非靜態(tài)成員
            //sex = "man"; error
            System.out.println("StaticTest()");
         }
    }
    public class Main{
     public static void main(String[] args) {
             //產(chǎn)生對象 實(shí)例化對象
            Person person = new Person();//person為對象的引用
            System.out.println(person.age);//默認(rèn)值為0
            System.out.println(person.name);//默認(rèn)值為null
            //System.out.println(person.count);//會有警告!
            //正確訪問方式:
            System.out.println(Person.count);
            System.out.println(Person.COUNT);
            Person.staticTest();
            //總結(jié):所有被static所修飾的方法或者屬性,全部不依賴于對象。
            person.eat();
            person.sleep();
     }
    }

    輸出結(jié)果為:

    0
    null
    0
    99
    StaticTest()
    eat()!
    sleep()!

    數(shù)據(jù)屬性的內(nèi)存布局:

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    四、封裝

    什么是封裝??簡單地來說,在我們寫代碼的時候經(jīng)常會涉及兩種角色: 類的實(shí)現(xiàn)者和類的調(diào)用者,而封裝能夠使得類的調(diào)用者不必關(guān)系類的實(shí)現(xiàn)者是如何實(shí)現(xiàn)類的,只要知道類中有什么方法直接調(diào)用即可。降低了類使用者的學(xué)習(xí)和使用成本, 從而降低了復(fù)雜程度。

    1. private實(shí)現(xiàn)封裝

    private/ public 這兩個關(guān)鍵字是訪問修飾限定符。

    被 public 修飾的成員變量或者成員方法, 可以直接被類的調(diào)用者使用被 private 修飾的成員變量或者成員方法, 不能被類的調(diào)用者使用

    直接使用public:

    class Person {
     public String name = "張三";
     public int age = 18; }
    class Test {
        public static void main(String[] args) {
            Person person = new Person();
            System.out.println("我叫" + person.name + ", 今年" + person.age + "歲");
       }
    }
    // 執(zhí)行結(jié)果
    我叫張三, 今年18歲

    這樣的代碼導(dǎo)致類的使用者(main方法的代碼)必須要了解 Person 類內(nèi)部的實(shí)現(xiàn), 才能夠使用這個類,學(xué)習(xí)成本較高。
    一旦類的實(shí)現(xiàn)者修改了代碼(例如把 name 改成 myName), 那么類的使用者就需要大規(guī)模的修改自己的代碼, 維護(hù)成本較高。

    使用private:

    class Person { 
     private String name = "張三"; 
     private int age = 18; 
     
     public void show() { 
     System.out.println("我叫" + name + ", 今年" + age + "歲"); 
     } 
    } 
    class Test { 
     public static void main(String[] args) { 
     Person person = new Person(); 
     person.show(); 
     } 
    } 
    // 執(zhí)行結(jié)果
    我叫張三, 今年18歲

    此時字段已經(jīng)使用 private 來修飾,類的調(diào)用者(main方法中)不能直接使用. 而需要借助 show 方法. 此時類的使用者就不必了解 Person 類的實(shí)現(xiàn)細(xì)節(jié)。

    同時如果類的實(shí)現(xiàn)者修改了字段的名字, 類的調(diào)用者不需要做出任何修改(類的調(diào)用者根本訪問不到 name, age這樣的字段)

    private 不光能修飾字段, 也能修飾方法

    通常情況下我們會把字段設(shè)為 private 屬性, 但是方法是否需要設(shè)為 public, 就需要視具體情形而定. 一般我們希望一個類只提供 “必要的” public 方法, 而不應(yīng)該是把所有的方法都設(shè)為 public。

    2.getter和setter方法

    被private修飾的字段不等于無法在類外使用該字段。那么如何在類外中獲取被private修飾的字段呢?此處jdk為我們提供了getter和setter方法 。

    代碼示例:

    class Person { 
     private String name;//實(shí)例成員變量
     private int age; 
     
     public void setName(String name){ 
     //name = name;//不能這樣寫,否則name仍為0,局部變量優(yōu)先
     this.name = name;//this引用,表示調(diào)用該方法的對象的name
     } 
     public String getName(){ 
     return name; 
     } 
     
     public void show(){ 
     System.out.println("name: "+name+" age: "+age); 
     } 
    } 
    public static void main(String[] args) { 
     Person person = new Person(); 
     person.setName("caocao"); 
     String name = person.getName(); 
     System.out.println(name); 
     person.show(); 
    } 
    // 運(yùn)行結(jié)果
    caocao 
    name: caocao age: 0

    注意事項(xiàng):

    • getName 即為 getter 方法, 表示獲取這個成員的值

    • setName 即為 setter 方法, 表示設(shè)置這個成員的值

    • 當(dāng)set方法的形參名字和類中的成員屬性的名字一樣的時候,如果不使用this, 相當(dāng)于自賦值. this 表示當(dāng)前實(shí)例的引用

    • 不是所有的字段都一定要提供 setter / getter 方法, 而是要根據(jù)實(shí)際情況決定提供哪種方法

    • 在 IDEA 中可以使用 alt + insert (或者 alt + F12) 快速生成 setter / getter 方法. 在 VSCode 中可以使用鼠標(biāo)右鍵菜單 -> 源代碼操作 中自動生成 setter / getter 方法

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    五、構(gòu)造方法

     1.構(gòu)造方法的基本語法及使用

    構(gòu)造方法是一種特殊方法, 使用關(guān)鍵字new實(shí)例化新對象時會被自動調(diào)用, 用于完成初始化操作。

    new 執(zhí)行過程:

    1. 為對象分配內(nèi)存空間

    2. 調(diào)用對象的構(gòu)造方法

    語法規(guī)則:

    1. 方法名稱必須與類名稱相同。

    2. 構(gòu)造方法沒有返回值類型聲明。

    3. 每一個類中一定至少存在一個構(gòu)造方法(如果沒有明確定義,則系統(tǒng)自動生成一個無參構(gòu)造方法)

    注意事項(xiàng):

    1. 如果類中沒有提供任何的構(gòu)造函數(shù),那么編譯器會默認(rèn)生成一個不帶有參數(shù)的構(gòu)造函數(shù)

    2. 若類中定義了構(gòu)造方法,則默認(rèn)的無參構(gòu)造將不再生成,如果再需要調(diào)用無參的構(gòu)造方法則需要手動寫一個。

    3. 構(gòu)造方法支持重載,規(guī)則和普通方法的重載一致。(對返回值不作要求,方法名相同,參數(shù)不同可包括參數(shù)個數(shù)不同或參數(shù)類型不同)

    代碼示例:

    class Person { 
     
     private String name;//實(shí)例成員變量
     private int age; 
     private String sex; 
     //默認(rèn)構(gòu)造函數(shù) 構(gòu)造對象 
     public Person() { 
     this.name = "caocao"; 
     this.age = 10; 
     this.sex = "男"; 
     } 
     //帶有3個參數(shù)的構(gòu)造函數(shù)
     public Person(String name,int age,String sex) { 
     this.name = name; 
     this.age = age; 
     this.sex = sex;
      } 
     public void show(){ 
     System.out.println("name: "+name+" age: "+age+" sex: "+sex); 
     } 
    } 
    public class Main{ 
     public static void main(String[] args) { 
     Person p1 = new Person();//調(diào)用不帶參數(shù)的構(gòu)造函數(shù) 如果程序沒有提供會調(diào)用不帶參數(shù)的構(gòu)造函數(shù)
     p1.show(); 
     Person p2 = new Person("zhangfei",80,"男");//調(diào)用帶有3個參數(shù)的構(gòu)造函數(shù)
     p2.show(); 
     } 
    } 
    // 執(zhí)行結(jié)果
    name: caocao age: 10 sex: 男
    name: zhangfei age: 80 sex: 男

    2.this關(guān)鍵字

    this表示當(dāng)前對象引用(注意不是當(dāng)前對象),可以借助 this 來訪問對象的字段和方法。this表示當(dāng)前對象引用是因?yàn)樵趧?chuàng)建對象的過程中會調(diào)用合適的構(gòu)造方法,而構(gòu)造方法內(nèi)部能夠用this關(guān)鍵字,而對象在創(chuàng)建的過程當(dāng)中(對象還未被創(chuàng)建出來)就使用了this關(guān)鍵字,證明this指向的是當(dāng)前對象的引用。

    class Person { 
     private String name;//實(shí)例成員變量
     private int age; 
     private String sex; 
     
     //默認(rèn)構(gòu)造函數(shù) 構(gòu)造對象
     public Person() { 
     //this調(diào)用構(gòu)造函數(shù)
     this("bit", 12, "man");//必須放在第一行進(jìn)行顯示
     } 
     
     //這兩個構(gòu)造函數(shù)之間的關(guān)系為重載。
     public Person(String name,int age,String sex) { 
     this.name = name; 
     this.age = age; 
     this.sex = sex; 
     } 
     public void show() { 
     System.out.println("name: "+name+" age: "+age+" sex: "+sex); 
     } 
    } 
    public class Main{ 
     public static void main(String[] args) { 
     Person person = new Person();//調(diào)用不帶參數(shù)的構(gòu)造函數(shù)
     person.show(); 
     }
    } 
    // 執(zhí)行結(jié)果
    name: bit age: 12 sex: man

    this既可以指的是當(dāng)前對象的引用中的屬性,也可以在構(gòu)造方法內(nèi)部使用(若是調(diào)用其它構(gòu)造方法則只能在構(gòu)造方法內(nèi)部使用)。

    代碼示例:

    class Person {
        private String name ;
        private  int age ;
        public Person() {
            this("zjr",18);
        }
        public Person(String name ,int age) {
            System.out.println("name:"+name+" age:"+age);
        }
    }
    public class TestDemo {
        public static void main(String[] args) {
            Person person =new Person();
        }
    }

    運(yùn)行結(jié)果:

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    結(jié)論:

    如果用this關(guān)鍵字調(diào)用其它構(gòu)造方法的放在第二行則會報(bào)錯;并且調(diào)用構(gòu)造方法只能調(diào)用一次。要習(xí)慣于使用this關(guān)鍵字,this關(guān)鍵字能夠有效地避免在對象的屬性賦值時兩邊變量名相同會出錯。

     六、Java中的代碼塊

    字段的初始化方式有:

    1. 就地初始化

    2. 使用構(gòu)造方法初始化

    3. 使用代碼塊初始化

    前兩種初始化方式都已介紹過,那么如何單純用代碼塊來初始化屬性??

    1.認(rèn)識代碼塊

    使用 {} 定義的一段代碼.

    根據(jù)代碼塊定義的位置以及關(guān)鍵字,又可分為以下四種:

    1. 普通代碼塊(只做了解)

    2. 構(gòu)造塊

    3. 靜態(tài)塊

    4. 同步代碼塊(后續(xù)講解多線程部分再談)

    2.普通代碼塊

    普通代碼塊:定義在方法中的代碼塊。

    public class Main{ 
     public static void main(String[] args) { 
     { //直接使用{}定義,普通方法塊
     int x = 10 ; 
     System.out.println("x1 = " +x); 
     } 
     int x = 100 ; 
     System.out.println("x2 = " +x); 
     } 
    } 
    // 執(zhí)行結(jié)果
    x1 = 10 
    x2 = 100

    3.構(gòu)造代碼塊

    構(gòu)造塊:定義在類中的代碼塊(不加修飾符)。也叫:實(shí)例代碼塊。構(gòu)造代碼塊一般用于初始化實(shí)例成員變量。

    代碼示例:

    class Person{ 
     private String name;//實(shí)例成員變量
     private int age; 
     private String sex; 
     
     public Person() { 
     System.out.println("I am Person init()!"); 
     } 
     
     //實(shí)例代碼塊
     { 
     this.name = "bit"; 
     this.age = 12; 
     this.sex = "man"; 
     System.out.println("I am instance init()!"); 
     } 
     
     public void show(){ 
     System.out.println("name: "+name+" age: "+age+" sex: "+sex); 
     } 
     
    } 
    public class Main { 
     public static void main(String[] args) { 
     Person p1 = new Person(); 
     p1.show(); 
     } 
    } 
    // 運(yùn)行結(jié)果
    I am instance init()! 
    I am Person init()! 
    name: bit age: 12 sex: man

    注意事項(xiàng): 實(shí)例代碼塊優(yōu)先于構(gòu)造函數(shù)執(zhí)行。

    4.靜態(tài)代碼塊

    使用static定義的代碼塊。一般用于初始化靜態(tài)成員屬性。

    class Person{
     private String name;//實(shí)例成員變量
     private int age; 
     private String sex; 
     private static int count = 0;//靜態(tài)成員變量 由類共享數(shù)據(jù) 方法區(qū)
     
     public Person(){ 
     System.out.println("I am Person init()!"); 
     } 
     
     //實(shí)例代碼塊
     { 
     this.name = "bit"; 
     this.age = 12; 
     this.sex = "man"; 
     System.out.println("I am instance init()!"); 
     } 
     
     //靜態(tài)代碼塊
     static { 
     count = 10;//只能訪問靜態(tài)數(shù)據(jù)成員 
     System.out.println("I am static init()!"); 
     } 
     
     public void show(){ 
     System.out.println("name: "+name+" age: "+age+" sex: "+sex); 
     } 
     
    } 
    public class Main { 
     public static void main(String[] args) { 
     Person p1 = new Person(); 
     Person p2 = new Person();//靜態(tài)代碼塊是否還會被執(zhí)行?
     } 
    }

    注意:

    1. 靜態(tài)代碼塊不管生成多少個對象,其只會執(zhí)行一次,且是最先執(zhí)行的。

    2. 靜態(tài)代碼塊執(zhí)行完畢后, 實(shí)例代碼塊(構(gòu)造塊)執(zhí)行,再然后是構(gòu)造函數(shù)執(zhí)行。

    3. 只有靜態(tài)代碼塊不需要實(shí)例化對象就能夠執(zhí)行。只要調(diào)用了類中的某個變量或方法(靜態(tài))就能夠被執(zhí)行。靜態(tài)代碼塊的執(zhí)行是在類的加載過程執(zhí)行的,因此只執(zhí)行一次。

    4. 靜態(tài)代碼塊的使用基變量本上跟static方法差不多,也不能出現(xiàn)this與定義被static修飾的變量,不依賴于對象。

    5. 靜態(tài)代碼塊中可以使用靜態(tài)變量,但是對于被靜態(tài)修飾的代碼塊與變量執(zhí)行的先后順序又不一樣,它是根據(jù)代碼的執(zhí)行先后順序決定的(前提是在初始化時已經(jīng)賦予初值,否則仍然遵循靜態(tài)代碼塊先執(zhí)行的順序)。例如:

    class Person {
        public String name ;
        public int age ;
        public static int count = 10 ;
        static {
            count=99;
            System.out.println("靜態(tài)");
    
        }
        {
            System.out.println("實(shí)例");
        }
    }
    public class TestDemo {
        public static void main(String[] args) {
            Person person = new Person();
            System.out.println(Person.count);
        }
    }

    運(yùn)行結(jié)果:

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    交換執(zhí)行先后順序:

    class Person {
            public String name ;
            public int age ;
            static {
                count=99;
                System.out.println("靜態(tài)");
    
            }
            public static int count = 10 ;
            {
            System.out.println("實(shí)例");
        }
    }
    public class TestDemo {
        public static void main(String[] args) {
            Person person = new Person();
            System.out.println(Person.count);
        }
    }

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    因此如果靜態(tài)變量沒賦初值,則結(jié)果是靜態(tài)代碼塊內(nèi)賦的值;如果靜態(tài)變量賦了初值,則按照執(zhí)行順序決定改變量最后的值,除了變量賦值語句執(zhí)行順序不同以外,靜態(tài)代碼塊內(nèi)的語句都是先執(zhí)行的。

    代碼塊中的重點(diǎn)是主要了解實(shí)例代碼塊、靜態(tài)代碼塊、構(gòu)造方法的運(yùn)行順序??偨Y(jié):先運(yùn)行的是靜態(tài)代碼塊,再運(yùn)行實(shí)例代碼塊(構(gòu)造代碼塊),最后運(yùn)行構(gòu)造方法。靜態(tài)代碼塊內(nèi)的只運(yùn)行一次。

    七、toString方法

    1.重寫println的toString方法

    我們剛剛注意到,我們在把對象的屬性進(jìn)行打印的時候,我們是自己實(shí)現(xiàn)了show函數(shù)。但在Java中它提供了一個給我們打印屬性的方法。叫toString方法。

    代碼示例:

    class Person { 
     private String name; 
     private int age; 
     public Person(String name,int age) { 
     this.age = age; 
     this.name = name; 
     } 
     public void show() { 
     System.out.println("name:"+name+" " + "age:"+age); 
     } 
     //重寫Object的toString方法
     @Override 
     public String toString() { 
     return "Person{" + 
     "name='" + name + '\'' + 
     ", age=" + age + 
     '}'; 
     } 
    } 
    public class Main { 
     public static void main(String[] args) {
      Person person = new Person("caocao",19); 
     person.show(); 
     System.out.println(person); 
     } 
    }
    // 執(zhí)行結(jié)果
    name:caocao age:19 
    Person{name='caocao', age=19}

    注意事項(xiàng):

    1. toString 方法會在 println 的時候被自動調(diào)用

    2. 將對象轉(zhuǎn)成字符串這樣的操作我們稱為序列化

    3. toString 是 Object 類提供的方法, 我們自己創(chuàng)建的 Person 類默認(rèn)繼承自 Object 類, 可以重寫 toString 方法實(shí)現(xiàn)我們自己版本的轉(zhuǎn)換字符串方法. (關(guān)于繼承和重寫這樣的概念, 我們后面會重點(diǎn)介紹).

    4. @Override 在 Java 中稱為 “注解”, 此處的 @Override 表示下面實(shí)現(xiàn)的 toString 方法是重寫了父類的方法,關(guān)于注解后面的課程會詳細(xì)介紹.

    5. IDEA快速生成Object的toString方法快捷鍵:alt+f12(insert)

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    若我們要觀察println中的toString方法,則我們可以按住ctrl鍵,將鼠標(biāo)點(diǎn)到println中的位置。點(diǎn)入println中會看到如圖所示:

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    再按ctrl鍵將鼠標(biāo)放在紅框處點(diǎn)入,看到的如圖所示:

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    最后將進(jìn)入紅框內(nèi)的方法當(dāng)中,如圖所示:

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    因此我們能夠證實(shí)println中的toString方法是按照哈希值來進(jìn)行處理后打印的。因此如果我們重寫了它的toString方法來打印我們類中的屬性,則直接System.out.println(person);即可(代碼如上所示),若沒有重寫println中的toString方法,則再用System.out.println(person);時打印的結(jié)果為:類名+@+經(jīng)過哈希值處理的地址。

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    2.匿名對象

    匿名只是表示沒有名字的對象

    1. 沒有引用的對象稱為匿名對象

    2. 匿名對象只能在創(chuàng)建對象時使用

    3. 如果一個對象只是用一次, 后面不需要用了, 可以考慮使用匿名對象

    class Person { 
     private String name; 
     private int age; 
     public Person(String name,int age) { 
     this.age = age; 
     this.name = name; 
     } 
     public void show() { 
     System.out.println("name:"+name+" " + "age:"+age); 
     } 
    } 
    public class Main { 
     public static void main(String[] args) { 
       new Person("caocao",19).show();//通過匿名對象調(diào)用方法
     } 
    } 
    // 執(zhí)行結(jié)果
    name:caocao age:19

    重點(diǎn):注意匿名對象是如何調(diào)用類中的方法的。

    八、交換兩個數(shù)的值(實(shí)參交換)

    代碼:

    class Test {
        private int num ;
    
        public int getNum() {
            return num;
        }
    
        public void setNum(int num) {
            this.num = num;
        }
    }
    public class TestDemo2 {
        public static void Swap(Test test1,Test test2) {
            int tmp = test1.getNum();
            test1.setNum(test2.getNum()) ;
            test2.setNum(tmp);
        }
        public static void main(String[] args) {
            Test test1 = new Test();
            Test test2 = new Test();
            test1.setNum(10);
            test2.setNum(20);
            System.out.println(test1.getNum());
            System.out.println(test2.getNum());
            Swap(test1,test2);
            System.out.println(test1.getNum());
            System.out.println(test2.getNum());
        }
    }

    運(yùn)行結(jié)果:

    Java中類與對象的相關(guān)知識點(diǎn)有哪些

    關(guān)于Java中類與對象的相關(guān)知識點(diǎn)有哪些就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

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

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

    AI