上海傳智播客JAVASE_day08學習筆記

《第八天總結》 張倫琦
《靜態、單例、繼承》
1.    靜態變量    
    1.1成員變量和內存示例
        成員變量,因爲都在成員中,是對象的成員。

        成員變量,隨對象創建在堆中,多份(每生成一個成員就生成一份)。



    1.2靜態變量和內存示例    
        靜態變量在變量的類型前,用關鍵字static聲明。

        靜態變量是類的變量,隨類的生成而生成在方法區的靜態區中,一個類生成一個,與對象的多少無關。



    1.3成員變和靜態變量的區別(局部變量和成員變量的區別)
        靜態變量和成員變量的區別?
        區別一:生命週期不同。
            靜態變量隨着類的加載而加載,隨着類的消失而消失。
            成員變量隨着對象的創建而創建,隨着對象的消失而消失。
        區別二:存儲空間不同。
            靜態變量存儲在靜態區。
            成員變量存儲在對象所在的堆內存。
        區別三:創建個數不同。
            靜態變量只有一份,被所有該類的對象共享。一改全改。
            成員變量有很多分,每個對象都獨享自己的成員變量。改動相互不影響。
        區別四:所屬元素不同。
            靜態變量屬於定義它的類,又叫類變量。
            成員變量屬於它所在的對象,又叫實例變量。
        區別五:訪問方式不同。
            靜態變量有兩種訪問形式 classname.xxx(Student.country)和objectname.xxx(stu.country)
            成員變量有一種訪問形式 objectname.xxx(stu.name)。。。。objectname(對象)
        成員變量和局部變量的區別?
        區別一:定義位置不同。
            成員變量定義在類中和對象相關。
            局部變量定義在方法中以及語句裏,和方法相關。
        區別二:存儲位置不同。
            成員變量存儲在堆內存的對象中。
            局部變量存儲在棧內存的方法中。
        區別三:存生命週期不同。
            成員變量隨着對象的創建而創建,隨着對象的消失而消失。
            局部變量隨着的方法的進棧而創建,隨着方法的彈棧而消失。
        區別四:作用範圍不同。
            成員變量因爲定義在類中,所以在類的{}內都有效。
            局部變量因爲定義在方法或代碼塊中,所以只在方法或代碼塊的{}內有效。
        區別五:初始化不同。
            成員變量因爲在堆內存中,所以有默認初始化值。
            局部變量因爲在棧內存中,所以沒有默認初始值,必須初始化後纔可以使用。
    

2.    靜態方法    
    2.1成員方法和靜態方法    
        靜態方法只能訪問靜態方法和靜態變量,不能訪問成員方法和成員變量,因爲這個時候成員方法還沒有生成呢
        成員方法既能訪問靜態變量和靜態方法,又能訪問成員方法和成員變量
        因爲:
            靜態方法,隨着類的加載而加載,隨着類的消失而消失。
            靜態方法加載進內存的時候堆中的對象可能還不存在,
            因此不能訪問和對象相關的成員變量和成員方法。
            成員方法是和對象相關的,對象的創建要比靜態方法晚,

            成員方法訪問已經存在的靜態方法是沒有問題的。



    2.2靜態方法main方法
            public static void main(String[] args)
            public:訪問修飾符,爲了jvm到處都能找到入口,所有給main最大的權限
            static:jvm啓動的時候還沒有對象,那它咋執行代碼捏?只好將方法聲明爲static,
                爲了不用對象通過類名來調用。
            void:無返回值。異常處理(暫時沒學)可以幫我們解決程序執行正確與否的問題,不需要返回值來判斷。
            main:歷史傳統都叫main
            String[]:字符串數組,要求調用main方法時候輸入信息。以前爲了用鍵盤輸入信息而設計,現在不用。

            args:arguments的簡寫。


    
    2.3靜態方法應用—數組工具類    
            工具類,靜態方法可以製作工具類,不需要工具類對象而直接使用工具類的功能。
            例子:
            class ArraysTool {
               //遍歷數組
               public static  void  printArray(int [] arr){
                   for (int i=0;i<arr.length ;i++ ){
                       System.out.println(arr[i]);
                   }
               }
               //得到最大值
               public static int  getMax(int [] arr){
                   int max=arr[0];
                   for (int i=1;i<arr.length ;i++ ){
                     if (arr[i]>max){
                         max=arr[i];
                     }
                   }
                   return max;
               }
               //得到最小值
               public static int  getMin(int [] arr){
                   int min=arr[0];
                   for (int i=1;i<arr.length ;i++ ){
                     if (arr[i]<min){
                         min=arr[i];
                     }
                   }
                   return min;
               }
            }

3.    靜態代碼塊    
    3.1靜態代碼塊
        靜態代碼塊,和類相關,類加載的時候執行一次,工具類使用時需要條件,怎麼滿足呢?在靜態代碼塊中處理。
        作用
           1.加載類的時候處理一些條件。
           2.給靜態變量初始化值。
    
            靜態代碼塊在類加載的時候執行一次,多用於給類初始化。
          1.靜態代碼塊,就是在類中用static關鍵字修飾的代碼塊!
          2.它在類加載的時候,只執行一次,並不是每次構建對象都執行的。
          3.它可以用於給初始靜態變量,和做一些類加載時期的準備工作
          4.類加載->靜態變量初始化->靜態代碼塊->構造方法
          5.靜態代碼塊和靜態變量,靜態方法一樣是和類相關的,不能直接訪問成員變量和成員方法,
            爲此時可能對象還不存在。
        例子:
        static{
            country="中國";
            System.out.println("static block is run");
        }

    3.2構造代碼塊    
        構造代碼塊,和對象相關,每次創建對象都要執行。
        作用
           1.創建對象的時候可以處理一些條件
           2.給成員變量初始化值

        構造代碼塊
        構造代碼塊隨着對象的創建而執行,多用於給對象初始化。
        1.構造代碼塊就是類中的一段獨立的代碼執行體,在每次構造對象的時候都會被執行。
        2.它可以用於給成員變量初始,和執行一些創建對象前的準備工作。
        3.它的地位和成員變量、成員方法類似,屬於對象相關的東西。
        4.成員變量初始-->構造代碼塊->構造方法
        例子:
        {
            name="張三丰";
            System.out.println("construct block is run");
        }
    3.3局部代碼塊
         局部代碼塊,和方法相關
         作用:
           1.組織方法中一個功能
           2.控制局部變量的作用範圍,生命週期
         例子:
        {
         int i=1;
         while(i<=10){
          System.out.println(i);
          i++;
         }
        }

4.    對象的創建過程    
        (如果有父類就先處理父類)類加載-->靜態變量初始化-->靜態代碼塊-->靜態方法-->成員變量的初始化-->構造代碼塊-->構造方法


        對象的創建順序。
         1.Person.class文件被加載進內存(如果有父類,將其父類的.class文件加載進內存)
         2.靜態變量默認初始化
         3.靜態變量顯示初始化
         4.靜態代碼塊執行
         5.成員變量默認初始化
         6.成員變量顯示初始化
         7.構造代碼塊執行
         8.構造方法初始化。
         9.對象創建完畢。
        
         注意:
         靜態元素是和類相關的,只有在第一次使用該類的時候執行一次,並且只執行一次。
         成員元素是和對象相關的,在每次創建對象的時候都要執行一次,可能執行很多次。

        構造方法和構造代碼塊
        1.構造方法是初始化特定對象的特定方式(new Person("張三",18))
        2.構造代碼塊是初始化所有對象的共同方式(new Person("張三",18) new Person())
        3.特定的初始化方式寫到構造方法中,共同的初始化方式寫到構造代碼塊中。

5.    單例模式    
    5.1單例模式的引入
        設計模式:
        模式:練武套路。少林拳,鐵砂掌。太極拳。
        建築學:窗口朝南,通風,寬敞明亮。豪華裝修
        軟件工程學,也有一些解決問題的特定套路。設計的時候就應該考慮。
        設計模式:23種經典設計模式,不侷限與23種。
        單例設計模式:要求一個只可以創建一個對象的類

    5.2單例模式的代碼體現(餓漢式)    
        //餓漢式(開發)。不會有多線程問題。
        class Student{
          private static  Student stu=new Student();//類加載的時候初始化一次,創建一個對象
          private Student(){
              //外面不能new對象
          }
          public static Student getInstance(){
              //可以得到這個唯一的對象
             return  stu;
          }
        }
        

    5.3單例模式的代碼體現(懶漢式)

        思想:
           問題:如果類外面能new Student()那將無法控制對象的個數。咋辦?
           答案:將學生類的構造方法私有化。
           問題:一個對象都無法在類外面創建了。咋辦?
           答案:在類內new 對象。對象有叫實例 instance
           問題:類和對象對無法訪問 getInstance(),咋辦?
           答案:將getInstance()聲明爲static
           問題:我多次調用getInstance()方法依然可以創建多個對象。咋辦?
           答案:將學生對象搞成靜態。
           問題:搞成靜態依然沒控制住。原因,對象不爲空你依然new對象造成的。
           答案:判定一下,對象爲空就new對象,不爲空就不new對象。
           問題:數據對外暴露不安全,
           答案:對數據private

        單線程有效,多線程無效。
        懶漢式(面試)
        class Student{
          private static /*final*/ Student stu;
          private Student(){
          }
          public static Student getInstance(){
        // 此時線程1要new沒new被叫停  線程2殺過來,創建一個對象,線程1醒來以後直接創建對象,導致對象不唯一。
              if (stu==null){
                 stu=new Student();;
              }
             return  stu;
          }
        }




6.    繼承    
    6.1繼承概述
        一、繼承定義:
           繼承就是子類從父類當中繼承下來成員變量和成員方法。
           如果有重名的成員變量和成員方法,將保留兩份,
           使用時,按先己後父原則查找。
        二、什麼時候能繼承?
           1.子類是父類的一種特殊類型的時候可以繼承。
             比如:蘋果是一種水果 ,梨子是一種水果,蘋果和梨子都可以繼承水果。
               學生是一種人,司機是一種人,學生和司機都可以繼承人。
           2.apple is a kind of fruit. 子類和父類存在is a關係。
              父類更加通用,子類更加具體。 子類和父類是一種更加具體的關係。
           3.父類中存放,從多個子類中抽取出來的共同的屬性和方法,子類中可以存儲,
            和子類自己相關的特有的屬性和方法。並不是所有的動物都和狗一樣能看家。
             子類和父類,子類是一種個性的體現,父類是一種共性的體現。
        三、Java中的繼承體系(單繼承)
           1.一個父類可以有多個直接子類。Animal有Cat和Dog兩個子類。
           2.一個子類有且只有一個直接父類。
           3.所有類的父類是Object類。
           4.單根(一個object根類)、多層(注意不要循環繼承)、一顆樹
        四、Java爲啥不能多繼承(爲啥不能有多個父類)
           會出現菱形問題,不知道用哪個方法。

    6.2繼承中子父類的同名變量
        /*
        繼承中的特殊
        */
        class Fu{
            int i=2;
        }
        class Zi extends Fu{
            int i=3;
            public void show(){
                System.out.println(i);
            }
        }
        class  BianliangDemo
        {
            public static void main(String[] args)
            {
                //Zi zi=new Zi();
                //zi.show();
                Zi zi=new Zi();
                zi.i=5;
                zi.show();
            }
        }

    6.3子父類中同名方法
        先己後父,皆無報錯!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章