Java學習筆記(8)
static修飾方法(靜態的成員方法):
訪問方式:
- 可以使用對象進行訪問 對象.靜態函數名();
- 可以使用類名進行訪問 類名.靜態函數名();
靜態函數要註意的事項:
- 靜態函數是可以使用類名或者對象進行調用的,而非靜態函數只能使用對象進行調用
- 靜態的函數可以直接訪問靜態的成員(函數與變量),但是不能直接訪問非靜態的成員。 原因:靜態函數是可以使用類名直接調用的,這時候可能還沒有存在對象,而非靜態的成員數據是隨著對象的存在而存在的。
- 非靜態的函數是可以直接訪問靜態與非靜態的成員 原因:非靜態函數只能由對象調用,當對象存在的時候,靜態數據老早就存在了,而非靜態數據也隨著對象的創建而存在了。
- 靜態函數不能出現this或者super關鍵字 原因:因為靜態的函數是可以使用類名調用的,一旦使用類名調用,這時候不存在對象,而this關鍵字是代表了一個函數的調用者對象,這時候產生了沖突。
推薦使用類名直接訪問靜態的成員 (節省內存 簡便)
靜態的數據的生命周期: 靜態的成員變量數據是優先於對象存在的。
靜態代碼塊是在類.calss文件加載到內存的時候就馬上執行的。
static什麽時候修飾一個函數呢? 答:如果一個函數沒有直接訪問到非靜態的成員時,那麽就可以使用static修飾了。 一般用於工具類型的方法
靜態函數不能訪問非靜態的成員? 不正確(不能直接訪問) 靜態函數只要存在有對象,那麽也可以訪問非靜態的數據。 只是不能直接訪問而已。
靜態的成員變量與非靜態的成員變量的區別:
作用上的區別:
- 靜態的成員變量共享一個數據給所有對象使用。
- 非靜態的成員變量的作用是描述一類事物的公共屬性
數量與存儲位置上的區別:
- 靜態成員變量是存儲方法區內存中,而且只會存在一份數據
- 非靜態的成員變量是存儲在堆內存中,有n個對象就有n份數據
生命周期的區別:
- 靜態的成員變量數據是隨著類的加載而存在,隨著類文件的消失而消失。
- 非靜態的成員數據是隨著對象的創建而存在,隨著對象被垃圾回收器回收而消失。
main函數的詳解:
- public 原因: 為了保證讓jvm在任何情況下都可以訪問到main方法
- static (靜態)靜態可以讓jvm調用main函數的時候更加的方便。不需要通過對象調用。
- 不使用static修飾的麻煩:
- 需要創建對象調用
- jvm不知道如何創建對象,因為創建對象有些是需要參數的,參數傳遞什麽東西呢?
- 不使用static修飾的麻煩:
- void 沒有返回值 因為返回的數據是給jvm。而jvm使用這個數據是沒有意義的,因為返回的時候意味這main函數結束了,所以這個數據也沒用了。所以就不要了。
- main 函數名。 註意:main並不是關鍵字,只不過是jvm能識別的一個特殊的函數名而已。
- arguments 參數 擔心某些程序在啟動時需要參數。
單例設計模式:保證一個類在內存中只有一個對象
模式:模式就是解決一類問題的固定步驟。
單例設計模式的步驟:(餓漢單例設計模式)
- 私有化構造函數
- 聲明本類的引用類型變量,並且使用該變量指向本類對象
- 提供一個公共靜態的方法獲取本類的對象
public class SingleCreative { public static void main(String[] args) { // TODO Auto-generated method stub Single1 s1=Single1.getInstance(); Single1 s2=Single1.getInstance(); System.out.println(s1==s2); } } class Single1{ private static Single1 s=new Single1(); private Single1() {} public static Single1 getInstance() { return s; } }
懶漢單例設計模式:
- 私有化構造函數
- 聲明本類的引用類型變量,但是不要創建對象
- 提供公共靜態的方法獲取本類的對象,獲取之前先判斷是否已經創建了本類的對象,如果已經創建了,那麽直接返回對象即可,如果還沒有創建,那麽先創建本類的對象,然後再返回
public class Single { public static void main(String[] args) { // TODO Auto-generated method stub Single2 s1=Single2.getInstance(); Single2 s2=Single2.getInstance(); System.out.println(s1==s2); } } class Single2{ private static Single2 s; private Single2() {} public static Single2 getInstance() { if (s==null) { s=new Single2(); } return s; }
推薦使用:餓漢單例設計模式 (因為懶漢單例設計模式會存在線程安全問題 )
繼承:繼承是通過關鍵字extends體現的 父類(超類 基類) 子類
繼承的格式:
class 類名1 extends 類名2{
}
繼承要註意的事項:
- 千萬不要為了減少重復代碼而去繼承,只有真正存在著繼承關系的時候才去繼承。
- 父類私有的成員不能被繼承。
- 父類的構造函數不能被繼承。
- 創建子類對象時默認會先調用父類無參的構造函數。
- 為什麽要調用父類的構造方法呢?這樣子做的意義在哪兒?
-
-
- 調用父類的構造方法是可以初始化從父類繼承下去的屬性的。
-
super關鍵字:super關鍵字代表了父類空間的引用。
super關鍵字的作用:
- 子父類存在著同名的成員時,在子類中默認時訪問子類的成員,可以通過super關鍵字指定訪問父類的成員
- 創建子類對象時,默認會先調用父類無參的構造方法,可以通過super關鍵字指定調用父類的構造方法
public class Demo1 { public static void main(String[] args) { // TODO Auto-generated method stub Zi z=new Zi("狗娃","鐵蛋"); z.print(); } } class Fu{ int x=10; String Name; public Fu() {} public Fu(String name) { this.Name=name; } public void eat() { System.out.println("小頭爸爸吃番薯"); } } class Zi extends Fu{ int x=20; String name; public Zi(String name,String Name) { this.name=name; super.Name=Name; } public void print() { super.eat(); eat(); System.out.println("名字=:"+super.Name); } public void eat() { System.out.println("大頭兒子吃龍蝦"); } }
super關鍵字調用父類構造方法要註意的事項:
- 如果在子類的構造方法上沒有指定調用父類的構造方法,那麽java編譯器會在子類的構造方法上面加上super()語句。
- super關鍵字調用父類的構造函數時,該語句必須要是子類構造函數中的第一個語句。
- super和this關鍵字不能同時出現在同一個構造函數中調用其他的構造函數。因為兩個語句都需要在第一位。
super關鍵字和this關鍵字的區別:
- 代表的事物不一致
- super關鍵字代表的是父類空間的引用 (代表一塊內存空間)
- this關鍵字代表的是所屬函數的調用者對象
- 使用前提不一樣
- super關鍵字必須要有繼承關系才能使用
- this關鍵字不需要存在繼承關系也可使用
- 調用構造函數的區別
- super關鍵字是調用父類的構造函數
- this關鍵字是調用本類的構造函數
方法的重寫:子父類出現了同名的函數,這個我們就稱為方法的重寫 (父類的功能無法滿足子類的需求時)
方法重寫的前提:必須要存在繼承的關系。
方法重寫要註意的事項:
- 方法重寫時,方法名與形參列表必須一致。
- 方法重寫時,子類的權限修飾符必須要大於或者等於父類的權限修飾符。 (public的權限比不寫的要大一點兒)
- 方法重寫時,子類的返回值類型必須要小於或者等於父類的返回值類型。
- 方法重寫時,子類拋出的異常類型要小於或者等於父類拋出的異常類型。 Exception (最壞) RuntimeException(小壞)
instanceof關鍵字:
instanceof的作用:判斷一個對象是否屬於指定的類別。
instanceof的使用前提:判斷的對象與指定的類別i必須要存在繼承或者實現的關系。 (可以對象是子類 也可以對象是父類 判斷的類別是它的子類)
instanceof關鍵字的使用格式: 對象 instanceof 類別 (是 返回true 不是 返回false)
Java學習筆記(8)