static:表示靜態的 static:可以用來修飾屬性、方法、代碼塊(或初始化塊)、內部類。 一、static修飾屬性(類變數): 1.由類創建的所有的對象,都共用這一個屬性。 2.當其中一個對象對此屬性進行修改,會導致其他對象對此屬性的一個調用。 VS 實例變數 (非 static 修飾的屬性, ...
static:表示靜態的
static:可以用來修飾屬性、方法、代碼塊(或初始化塊)、內部類。
一、static修飾屬性(類變數):
public class TestStatic { //static修飾屬性 private static int id; //static修飾方法 public static void getId(){ System.out.println(id); } //static修飾代碼塊 static{ System.out.println(id); } //static修飾內部類 static class A{ private String name; } }
1.由類創建的所有的對象,都共用這一個屬性。
2.當其中一個對象對此屬性進行修改,會導致其他對象對此屬性的一個調用。 VS 實例變數 (非 static 修飾的屬性,各個對象各自擁有一套副本)。
A a1 = new A(); a1.setId(1001); System.out.println(a1.getId());//a1輸出為1001 A a2 = new A(); System.out.println(a2.getId());//a2輸出也為1001 System.out.println(a1.getId() == a2.getId());//輸出為true
3.類變數隨著類的載入而載入,而且單獨一份。
4.靜態的變數可以直接通過 “類.類變數” 的形式來調用。
5.類變數的載入要早於對象。所以當有對象以後,可以 “對象.類變數” 使用,但是 “類.實例變數” 是不行的。
public class TestStatic { public static void main(String[] args) { //"類.類變數" 調用 System.out.println(A.id); // "對象.類變數" 調用 A a1 = new A(); System.out.println(a1.id); } } class A{ public static int id = 1001; public static int getId() { return id; } public static void setId(int id) { A.id = id; } }
6.類變數存在於靜態域中。
二、static修飾方法(類方法):
1.隨著類的載入而載入,在記憶體中也單獨一份。
2.可以直接通過 “類.類方法” 的方式調用。
//"類.類方法" 調用靜態方法 A.setId(1002);
3.內部可以調用靜態的屬性或靜態的方法,而不能調用非靜態的屬性和方法。反之,非靜態的方法是可以調用靜態的屬性和方法。
4.靜態的方法內不可以有 this 或 super 關鍵字的!
class A{ public static int id = 1001; private String name; public static int getId() { //test(); 靜態方法不可以調用非靜態的屬性和方法 //this.name = "小明"; 靜態的方法內不可以有 this 或 super 關鍵字的! return id; } public void test(){ //非靜態的方法是可以調用靜態的屬性和方法 A.id = 1002; getId(); } }
註:靜態的結構(static 的屬性、方法、代碼塊、內部類)的生命周期要早於非靜態的結構,同時被回收也要晚於非靜態的結構。
static 面試題:
public class TestStatic { public static void main(String[] args) { B b = new B(); b.test(); //輸出結果是什麼? } } class A{ static{ System.out.println("A"); } public A(){ System.out.println("B"); } } class B extends A{ static{ System.out.println("C"); } public B(){ System.out.println("D"); } public void test(){ System.out.println("E"); } } //輸出結果的順序為:A ——> C ——> B ——> D ——> E
abstract:表示抽象的
abstract:可以用來修飾類和方法。
abstract class A{ public abstract void test(); }
一、abstract 修飾類:抽象類
1.不可被實例化。(不能 new)
2.抽象類有構造器 。(凡是類都有構造器)
3.抽象方法所在的類,一定是抽象類。
abstract class A{ public abstract void test(); public A(){} //抽象類有構造器 }
4.抽象類中可以沒有抽象方法。
abstract class K{ public void test(){ System.out.println("抽象類中可以沒有抽象方法"); } }
5.當我們設計一個類,不需要創建此類的實體的時候,就可以考慮將其設置為抽象的,由其子類實現這個類的抽象方法以後,就進行實例化。
二、abstract 修飾方法:抽象方法
1.抽象方法只保留方法的功能,而具體的執行,交給繼承抽象類的子類,由子類重寫此抽象方法。
2.若子類繼承抽象類,並重寫了所有的抽象方法,則此類是一個 “實體類” ,既可以實例化。
3.若子類繼承抽象類,但是沒有重寫所有的抽象方法,意味著此類中仍有抽象方法,則此類必須聲明為抽象的類。
public class TestAbstract { public static void main(String[] args) { //People p = new People(); 抽象類不可被實例化 Worker w = new Worker(); w.show(); w.test(); } } abstract class People{ public abstract void test(); public abstract void show(); } class Worker extends People{ public Worker(){} @Override public void test() { System.out.println("重寫 test() 方法"); } @Override public void show() { System.out.println("重寫 show() 方法"); } }