6-JavaOOP關鍵字和思考

static關鍵字

(1)如果沒有static會怎樣?

  • 定義Person類

    • 姓名、年齡、國籍,說話行為
    • 多個構造,重載形式體現
  • 中國人的國籍都是確定的

    • 國籍可以進行顯示初始化
class Person {
    String name;
    int age;
    String gender;
    String country = "CN";
    Person() {}
Person(String name, int age, String gender, String country) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.country = country;
    }

    void speak() {
        System.out.println("國籍:" + country + " 姓名:" + name + " 性別:" + gender + " 年齡:" + age + " 哈哈!!!");
    }}

(2)new Person 對象

  • 分析內存
  • 每個對象都維護實例變量國籍也是。
  • (3)內存分析
    • 棧,堆、共享區

    • Demo.class加載近共享區

    • Demo類的main方法進棧
      Person p1=new Person();

    • Person.class 加載進方法區

      • 堆內存開辟空間,實例變量進行默認初始化,顯示初始化。
        內存地址傳給變量p1,棧和堆建立連接
        person p2=new Person();
      • 堆內存開辟空間,實例變量進行默認初始化,顯示初始化。
        內存地址傳給變量p2,棧和堆建立連接
問題1:為了讓所有Person對象都共享一個country ,可以嘗試將country放入共享區。
問題2:country變量如何放入共享區?對象如何訪問?

方案一:使用static

  • 2:static
    1:為了實現對象之間重復屬性的數據共享

  • 3:static使用
    1:主要用于修飾類的成員
    1:成員變量
    1:非靜態成員變量:需要創建對象來訪問
    2:靜態成員變量:使用類名直接調用,也可以通過對象訪問

方案二:成員方法
可以使用類名直接調用

  • 靜態函數:
    1:靜態函數中不能訪問非靜態成員變量,只能訪問靜態變量。
    2:靜態方法不可以定義this,super關鍵字.
    3:因為靜態優先于對象存在.靜態方法中更不可以出現this
    非靜態函數:非靜態函數中可以訪問靜態成員變量

細節:
1:靜態函數中不能使用非靜態變量
2:非靜態函數可以訪問靜態變量

問題3:為什么靜態函數中不能訪問非靜態成員

    1:static修飾的成員在共享區中。優先于對象存在
    2:驗證
        1:使用靜態代碼塊驗證
            1:靜態代碼塊
                static{
                    靜態代碼塊執行語句;
                }
             1:靜態代碼塊特點

隨著類的加載而加載。只執行一次,優先于主函數。用于給類進行初始化。

總結:
static特點

  • 隨著類的加載而加載,靜態會隨著類的加載而加載,隨著類的消失而消失。說明它的生命周期很長。
  • 優先于對象存在。-->靜態是先存在,對象是后存在。
  • 被所有實例(對象)所共享。
  • 可以直接被類名調用
    5:靜態變量(類變量)和實例變量的區別:
    1存放位置
    1:類變量隨著類的加載而加載存在于方法區中.
    2:實例變量隨著對象的建立而存在于堆內存中.
    2生命周期
    1:類變量生命周期最長,隨著類的消失而消失.
    2:實例變量生命周期隨著對象的消失而消失.

靜態優缺點

  • 優點:對對象的共享數據進行單獨空間的存儲,節省空間 例如Person 都有
    國籍。該數據可以共享可以被類名調
  • 缺點:生命周期過長
    • 訪問出現局限性。(靜態只能訪問靜態)

問題4:什么時候定義靜態變量

  • 靜態變量(類變量)當對象中出現共享數據
  • 例如:學生的學校名稱。學校名稱可以共享,對象的數據要定義為非靜態的存放在對內存中(學生的姓名,學生的年齡)

問題5:什么時候定義靜態函數

  • 如果功能內部沒有訪問到非靜態數據(對象的特有數據。那么該功能就可以定義為靜態)

靜態的應用:自定義數組工具類

main方法詳解

主函數是靜態的
```public static void main(String[] args){
}

主函數是什么:主函數是一個特殊的函數,作為程序的入口,可以被jvm識別。
- 主函數的定義:
           public :代表該函數的訪問權限是最大的。
           static :代表主函數隨著類的加載,就已經存在了。
           void:  主函數沒有具體的返回值
           main : 不是關鍵字,是一個特殊的單詞可以被jvm識別。
           (String[] args) 函數的參數,參數類型是一個數組,該數組中的元素是字符串。字符串類型的數組。
           主函數的格式是固定的:jvm能夠識別
           jvm在調用函數是,傳入的是new String[0];
可以在dos窗口中執行 java  Demo5   hello  world   給類Demo5的main方法傳遞2個參數,參數與參數之間通過空格隔開。



#####單例設計模式:一些人總結出來用來解決特定問題的固定的解決方案。
解決一個類在內存中只存在一個對象,想要保證對象的唯一。
1 為了避免其他程序過多的建立該類對象。禁止其他程序建立該類對象。
2 為了其他程序可以訪問該類對象,在本類中自定義一個對象。
3 方便其他程序對自定義類的對象的訪問,對外提供一些訪問方式。
 代碼:
1將構造函數私有化
2在類中創建一個私有的本類對象
3提供一個用類名調用的公有方法獲取該對象。

####繼承
類和類之間的常見關系。
-  既然繼承是描述類和類之間的關系,就需要先來了解類和類之間的常見關系
現實生活的整體與部分
*舉例說明*

    - 1:學生   是人  
    - 2:狗     是動物
    - 3:球隊 包含 球員 整體與部分的關系,部分可以刪除和增加
    - 4:筆記本包含 cpu 整體與部分的關系,部分不可以刪除和增加
    - 5:航母編隊 包含(航母 護衛艦 驅逐艦 艦載機 核潛艇)

**java中的類與類關系
java中的類關系
1:is a 關系 (學生是人)
2:has a 整體與部分
**
    

####繼承
- 1:描述一個學生類
  - 1:姓名年齡學號屬性,學習的方法
- 2:描述一個工人類
 - 1:姓名年齡工號屬性,工作的方法
- 3:描述一個人類
  - 1:姓名年齡屬性,說話的方法。
- 4:發現學生類和人類天生有著聯系,學生和工人都是人。所以人有的屬性和行為學生和工人都會有。出現類代碼重復

*問題:*
- 1:如果沒有繼承,出現類和類的關系無法描述
- 2:如果沒有繼承,類和類之間有關系會出現類和類的描述代碼的重復

*繼承特點*
- 1:描述類和類之間的關系
-  2:降低類和類之間的重復代碼
- 3:降低對象和對象之間的代碼重復使用靜態變量
- 4:降低類和類之間的代碼重復使用就繼承
    
##extends關鍵字
**[1]、繼承使用extends關鍵字實現**
- 1:發現學生是人,工人是人。顯然屬于is a 的關系,is a就是繼承。
- 2:誰繼承誰?
    - 學生繼承人,發現學生里的成員變量,姓名和年齡,人里邊也都進行了定義。有重  復代碼將學生類的重復代碼注釋掉,創建學生類對象,仍然可以獲取到注釋的成員。這就是因為繼承的關系,學生類(子類)繼承了人類(父類)的部分


**[2]、繼承細節;**   
- 類名的設定,被繼承的類稱之為父類(基類),繼承的類稱之為子類
    - 2:子類并不能繼承父類中所有的成員

- 父類定義完整的成員 靜態成員,非靜態,構造方法。靜態變量和靜態方
法都可以通過子類名.父類靜態成員的形式調用成功。
    - 2:所有的私有成員不能繼承,private修飾的成員。
    - 3:構造函數不能被繼承

- 如何使用繼承
 - 不要為了使用繼承而繼承。工人和學生都有共性的成員,不要為了節省代
碼,讓工人繼承學生。


##super關鍵字

- 定義Father(父類)類
    - 成員變量int x=1;
    - 構造方法無參的和有參的,有輸出語句
- 定義Son類extends Father類
    - 成員變量int y=1;
    - 構造方法無參和有參的。有輸出語句
    this.y=y+x;
- 創建Son類對象
        Son son=new Son(3);
        System.out.println(son.y); //4


- 子類對象為什么可以訪問父類的成員。
        1:this.y=y+x;有一個隱式的super super.x

**super關鍵字作用**
- 主要存在于子類方法中,用于指向子類對象中父類對象。
- 訪問父類的屬性
- 訪問父類的函數
- 訪問父類的構造函數

**super注意**
- this和super很像,this指向的是當前對象的調用,super指向的是當前調用對象的父類。Demo類被加載,執行main方法,Son.class加載,發現有父類Father類,于是Father類也加載進內存。類加載完畢,創建對象,父類的構造方法會被調用(默認自動無參),然后執行子類相應構造創建了一個子類對象,該子類對象還包含了一個父類對象。該父類對象在子類對象內部。this super只能在有對象的前提下使用,不能在靜態上下文使用。
- 子類的構造函數默認第一行會默認調用父類無參的構造函數,隱式語句
super();
    - 父類無參構造函數不存在,編譯報錯。
   
- 子類顯式調用父類構造函數
在子類構造函數第一行通過super關鍵字調用父類任何構造函數。如果顯式調用父類構造函數,編譯器自動添加的調用父類無參數的構造就消失。構造函數間的調用只能放在第一行,只能調用一次。super() 和this()不能同時存在構造函數第一行。




**super思考**
如果開發者自定義了一個類,沒有顯示的進行類的繼承,那么該類中成員函數是否可以使用super關健健字?可以使用,繼承了Object類,Object類是所有類的父類。

    
##重寫(Override)
**在繼承中,子類可以定義和父類相同的名稱且參數列表一致的函數,將這種函數
稱之為函數的重寫.**
- 定義Father類
  - 姓名,吃飯方法,吃窩窩頭。
    - 定義Son類,繼承Father
        - Son類中不定義任何成員,子類創建對象,仍然可以調用吃飯的方法。
        - 父類的吃飯的方法,Son不愿吃。Son自己定義了吃飯的方法。

*此時父類中有一個吃飯的方法,子類中有2個吃飯的方法,一模一樣,只是方法體不一樣。*
*一個類中兩個函數一模一樣,是不允許的。*
(1)編譯運行,執行了子類的方法。
(2)使用父類的方法,在子類方法中,使用super.父類方法名。


**前提**:
必須要有繼承關系

**特點**
- 當子類重寫了父類的函數,那么子類的對象如果調用該函數,一定調用的是重寫過后的函數。可以通過super關鍵字進行父類的重寫函數的調用。
- 繼承可以使得子類增強父類的方法

**細節**
- 函數名必須相同
- 參數列表必須相同
- 子類重寫父類的函數的時候,函數的訪問權限必須大于等于父類的函數的訪
問權限否則編譯報錯
- 子類重寫父類的函數的時候,返回值類型必須是父類函數的返回值類型或該返回值類型的子類。不能返回比父類更大的數據類型: 如子類函數返回值類型是Object

        1:定義 A B  C 類 B extends A  
        2:Father類中定義A getA();
        3:Son 類中重寫getA(); 方法,嘗試將返回值修改為B,C ,Object
            1:B編譯通過
            2:C 編譯失敗 ,沒有繼承關系
            3:Object編譯失敗,比父類的返回值類型更大


- 子類對象查找屬性或方法時的順序:
    - 原則:就近原則。
如果子類的對象調用方法,默認先使用this進行查找,如果當前對象沒有找到屬性或方法,找當前對象中維護的super關鍵字指向的對象,如果還沒有找到編譯報錯,找到直接調用。
- 重載和重寫的不同
    - 重載(overload):  
        所有的重載函數必須在同一個類中 
        - 特點: 
            函數名相同,參數列表不同,與其他的無關(訪問控制符、返回值類型)
     - 不同:
            個數不同 、 順序不同、 類型不同 
  -   重寫(override):
         1:前提: 繼承
        2:特點:
              函數名必須相同、參數列表必須相同。
              子類的返回值類型要等于或者小于父類的返回值

##instanceof 關鍵字

  *instanceof是什么?*
  - 屬于比較運算符:
 - instanceof關鍵字:該關鍵字用來判斷一個對象是否是指定類的對象。
 - 用法:對象  instanceof 類;   
      該表達式是一個比較運算符,返回的結果是boolea類型  true|false
    **注意:使用instanceof關鍵字做判斷時,兩個類之間必須有關系。**

show me code
定義一個功能表函數,根據傳遞進來的對象的做不同的事情,如果是狗讓其看家,如果是貓讓其抓老鼠
        1:定義動物類
        2:定義狗類繼承動物類
        3:定義貓類繼承動物類
        4:定義功能根據傳入的動物,執行具體的功能

**instanceof好處
            可以判斷對象是否是某一個類的實例    **


##final關鍵字

需求: 
1:定義靜態方法求圓的面積
    2:定義靜態方法求圓的周長
    3:發現方法中有重復的代碼,就是PI,圓周率。
 -  如果需要提高計算精度,就需要修改每個方法中圓周率。
    
4:描述一個變量
  - 方法都是靜態的,靜態只能訪問靜態,所以變量也定義為靜態的。
<code>public static double PI=3.14;</code>
  - 如果定義為public后,新的問題,類名.PI=300; 改變了PI的值。
  - 修改為private,修改為private后進行了封裝,需要getset公共訪問方法。
3)現有的知識不能解決這樣的問題了。可以使用final

**使用final**
- final關鍵字主要用于修飾類、類成員、方法、以及方法的形參。
- final修飾成員屬性:

            1:說明該成員屬性是常量,不能被修改。
                public static final double PI=3.14;
                1:public :訪問權限最大
                2:static :內存中只有一份
                3:final  :是一個常量
                4:常量名大寫
                5:必須初賦值。

            2:使用類名.成員。修改該成員的值,報錯。--常量不能被修改
                1:基本數據類型,final使值不變
- 對象引用,final使其引用恒定不變,無法讓其指向一個新的對象,但是對象自身卻可以被修改。
                3:該關鍵字一般和static關鍵字結合使用
                    1:常量可以優先加載,不必等到創建對象的時候再初始化。
                4:final和static可以互換位置
                5:常量一般被修飾為final
            3:fianl修飾類:
                1:該類是最終類,不能被繼承。
                    1:將父類加final修飾,子類繼承,就會報錯。
*查看api文檔發現String類是final的。Integer類也是final的*
                    1:為了防止代碼功能被重寫
                    2:該類沒有必要進行擴展
            4:final修飾方法:
                1:該方法是最終方法,不能被重寫
- 當一個類被繼承,那么所有的非私有函數都將被繼承,如果函數不想被子類繼承并重寫可以將該函數final修飾   
                3:當一個類中的函數都被修飾為final時,可以將類定義為final的。


            5:final關鍵字修飾形參
                1:當形參被修飾為final,那么該形參所屬的方法中不能被篡改。
- 項目中主要用于一些只用來遍歷未知數據的函數。將未知變量聲明為final的。增強數據的安全性。


**思考**
- 為什么子類一定要訪問父類的構造函數呢
1:子類繼承了父類的屬性,如果要使用父類的屬性必須初始化,創建子類對象,必須先初始化父類屬性,必須調用父類的構造方法。
  - 為什么調用父類無參的構造函數
設計java語言之時,只知道編譯器會默認添加無參的構造函數,有參的無法確定,但是可以通過super關鍵字顯式調用父類指定構造函數。
  - 為什么super()this()語句要放在構造函數的第一行
子類可能會用到父類的屬性,所以必須先初始化父類。
- 靜態和非靜態的區別。說一下內存。
- 成員變量和靜態變量的區別?
- 靜態的特點以及注意事項?
- 什么時候使用靜態?
- 繼承的好處?
- java改良多繼承的原因?
- 當使用一個已存在的繼承體系時,該如何更快應用 
- 什么時候用繼承?
- super和this的特點?
- 覆蓋的特點,何時應用,注意事項?
- 子類的實例化過程?為什么是這樣的實例化過程?
- super語句,和this語句為什么不能同時存在,super為什么要定義在第一行?
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 一:java概述:1,JDK:Java Development Kit,java的開發和運行環境,java的開發工...
    ZaneInTheSun閱讀 2,688評論 0 11
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • Advanced Language Features 知識點:一. static修飾符 static修飾符可以用來...
    風景涼閱讀 459評論 0 0
  • 1、.java源文件: 一個以”.java“為后綴的源文件:只能有一個與文件名相同的類,可以包含其他類。 2、類方...
    Hughman閱讀 1,523評論 1 9
  • 文字 某一刻 與你結緣 沒有它的日子 度日如年 每一天 我在寫你、讀你、看你 成為一個影子 無時無刻的出現 你讓我...
    我愛吃任何魚閱讀 113評論 0 2