2020/3/19學習筆記day22【JAVA的高級特性(一)】

java-day22

重載、重寫和多態的關係

  • 重載是編譯時多態
    • 在調用重載方法的時候,在編譯期間就要確定調用的方法到底是哪一個,如果不能確定,那麼就編譯報錯。
  • 重寫是運行時多態
    • 調用重寫方法的時候,在運行期間才能確定這個方法到底是哪一個對象中的。這個事情取決於調用方法的引用在運行期間到底指向的對象是誰,以及對象中有沒有重載這個方法。
    • java中的方法調用,是運行時動態和對象綁定的。

JAVA的高級特性(一)

學習目標

  1. 靜態屬性、方法、代碼塊
  2. 靜態導入
  3. final類、方法、變量
  4. 訪問控制修飾符
  5. 抽象類和抽象方法
  6. 接口
  7. 內部類
  8. 區別 “ == ” 和 equals()

靜態變量

  • 被所有實例變量共享
  • 可被類的外面訪問
  • 更像是一個全局變量
  • 訪問方法:類名.靜態方法名

static修飾符

  1. 在類中,使用static修飾的成負變量,就是靜態變量,反正爲非靜態變量。

    • pub1ic class Student{
      	private static int a;
      	private int b;
      }
      
  2. 靜態類和非靜態變量的區別

    • 靜態變量是屬於類的,[可以] 使用類名來訪問,[也可以]使用對象來訪問。

    • 非靜態變量是屬於對象的,[只能]使用對象來訪問

    • pub1ic class Student{
      	private static int a;
      	private int b;
      }
      
      main:
          Student stu = new Student();
          //使用對象訪問類中非靜態變量
          System.out.println(stu.b);
      
          //使用對象訪問類中靜態變量
          System.out.println(stu.a);
      
          //使用類名訪問類中靜態變量
          System.out.print1n(Student.a);
      
      
  3. 靜態屬性和非靜態屬性在內存中的區別

    1. 一個類中的靜態屬性,在內存中只有一份,它是這個類所以的實例對象所共享的

    2. 一個類中的非靜態屬性,每次創建一個新的對象,在這個新的對象中就會有一份這個非靜態屬性。對象和對象之間的非靜態屬性是互不影響的。

    3. package com.zzb.day22;
      
      public class Student{
      
      	private static int count;
      	private int age;
      
      	public Student(){
      		count++;
      		age++;
      	}
      
      	public static void main(String[] args){
      		Student s1 = new Student();
      		Student s2 = new Student();
      		Student s3 = new Student();
      		Student s4 = new Student();
      
      		System.out.println(s1.age);
      		System.out.println(s2.age);
      		System.out.println(s3.age);
      		System.out.println(s4.age);
      
      		System.out.println("------------------------");
      		System.out.println(s1.count);
      		System.out.println(s2.count);
      		System.out.println(s3.count);
      		System.out.println(s4.count);
      		System.out.println("------------------------");
      		System.out.println(Student.count);
      	}
      }
      

      在這裏插入圖片描述

      在這裏插入圖片描述

    4. 注意,靜態變量是屬於類的,是這個類的所有對象共享的,非靜態變量是屬於對象的,是每個對象獨有的。在類中,使用static修飾符修飾的方法就是靜態方法,反之爲非靜態方法

    • 靜態方法是屬於類的,[可以] 使用類名直接訪問.

    • 非靜態方法是屬於對象綁定,[必須] 使用對象名來訪問

    • 靜態方法中[不可以]直接訪問類中的非靜態屬性和非靜態方法,但是反過來,類中的非靜態方法中[可以]直接訪問類中的靜態方法和靜態屬性。

    • this和super都屬於非靜態的變量,靜態方法中無法使用這兩個關鍵字

    • package com.zzb.day22;
      
      public class Student{
      
      	private static int count;
      	private int age;
      	
          public void run(){}
          public static void go(){}
          
          public static void test(){
              //編譯報錯
              //System.out.println(this);
              //System.out.println(age);
              //System.out.println(this.age);
              
              //編譯通過,直接訪問類中的靜態屬性
              //和靜態方法
              System.out.println(count);
              go();
          }
      }			
      
  4. 思考,爲什麼靜態方法中不可以訪問非靜態的屬性和訪問,非靜態的方法中卻可以訪問靜態的屬性和方法?

    • 類中的屬性和方法,都必須分配內存空間,在其中進行初始化操作之後,才能被訪問和調用。靜態的屬性和方法,在類被加載到內存之後,已經在一-個叫靜態代碼區的內存區域中,專門的做好了初始化相關的操作,這些屬性和方法隨便可以被類進行調用
    • 非靜態屬性和方法,是在使用new關鍵字創建對象之後,在對象所佔據的內存空間中,完成了對這些非靜態屬性和方法的初始化相關工作,在這之後,我們纔可以使用對象來訪問這些非靜態的屬性和方法。
    • 從初始化的時間點來看,可以知道靜態的屬性和方法在初始化完成可以被調用的時候,那些非靜態的屬性和方法還沒有完成對應的初始化工作,不能被調用。所以靜態方法中無法直接訪問非靜態的屬性和方法。但是非靜態屬性和方法完成初始化工作,可以被調用的時候,類中的那些靜態屬性和方法,早就完成了初始化工作,所以非靜態方法中可以直接調用類中的靜態屬性和方法。
  5. 父類中的靜態方法可以被子類繼承,但是不能被子類重寫

    • public class Person{
          public static void say(){}
      }
      
      public class Student extends Person{
          //編譯報錯
          //靜態方法可以繼承不能重寫
          //public void say(){}
          
          //編譯通過,但不是重寫
          public static void say(){}
          
      }
      
  6. 代碼塊和靜態代碼塊

    • public class Person{
          {
              //代碼塊(匿名代碼塊)
          }
          
          static{
              //靜態代碼塊
          }
      } 
      
    • 匿名代碼塊和靜態代碼塊的調用

      • 因爲都沒有名字,代碼中並不能直接調用這兩種代碼塊
      • 匿名代碼塊是在創建對象的時候自動調用,並且是在類的構造器執行之前。如果我們連續多次創建對象,每次創建對象都會調用這個匿名代碼塊。
      • 靜態代碼塊,會在類加載到內存的時候,自動執行一次,並且只會執行這一次。因爲這個類加載到內存之後,就不會再加載這個類了。
        在這裏插入圖片描述
    • 匿名代碼塊和靜態代碼塊的作用

      • 匿名代碼塊的作用,是給對象裏面的非靜態屬性進行初始化賦值的。

      • 構造器的作用有兩個,一個是配合new關鍵字創建對象,另一個就是給對象中的屬性做初始化。所以我們平
        時見到的匿名代碼塊並不多,因爲它的工作是可以被構造器代替的。並且構造器是有名字的,可以使用this()的語法來調用,但是匿名代碼塊沒有名字,一般不會主動去調用

      • 靜態代碼塊的作用,是給類中的靜態屬性做初始化,也可以在類加載的時候就給這個類本身做一些其他的初始化工作,因爲靜態代碼塊執行的時間點比較早,所以我們在靜態代碼塊中編寫的代碼就可以很早的得到執行,提前得到一些初始化操作。例如可以在靜態代碼塊中,早早對靜態屬性進行初始化賦值工作。

      • public class Student{    
            public static String name;    
            public Student(){        
                name = "Tom";    
            }    
            public static void main(String[] args){        
                //輸出null,繞過構造器直接拿值        
                //沒有創建對象構造器沒有執行,初始化沒有完成        
                //訪問的是默認值null        
                System.out.println(Student.name);    
            }
        }
        
      • 如何解決? 使用靜態代碼塊

      • public class Student{    
            public static String name;    
            static{        
                name = "Tom";    
            }    
            public static void main(String[] args){               
                //訪問的是默認值Tom       
                System.out.println(Student.name);    
            }
        }
        
  7. 創建和初始化的過程

    1. Student s = new Student();
      
    2. 假設Student類之前沒有被加載過

      1. 類加載,同時初始化靜態屬性的默認值

        •  0 false null
          
      2. 執行靜態代碼塊

      3. 分配內存空間,同時初始化非靜態屬性的默認值 0 false null

      4. 調用父類構造器 super( )

      5. 對Student對象中的非靜態屬性做顯示賦值

        •  private static name = "Tom";  
          
      6. 執行匿名代碼塊

      7. 執行Student類中的構造器

      8. 把創建好的對象內存地址值,賦值給變量s(=)

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Qywpt73K-1584610981133)(3-19.assets/1584607250042.png)]

  8. 創建對象的時候需要做初始化

    • 靜態屬性

    • 非靜態屬性

      1. 子類的非靜態屬性

      2. 父類的非靜態屬性

    • 第一梯隊:靜態屬性 優先初始化

      • 類加載(把編譯好的class文件加載到內存) 靜態代碼塊
    • 第二梯隊:父類中的非靜態屬性

      • super()這種特殊語法
    • 第三梯隊:子類中的非靜態屬性

      • 匿名代碼庫 構造器
  9. 經典案例

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-4y8PNs44-1584610981134)(3-19.assets/1584610869174.png)]

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