java基礎學習之小知識點篇一
java基礎學習之小知識點
1.程式碼塊
解釋: { } 之間的就是程式碼塊。
分類
-
區域性程式碼塊(方法中) :限定變數的生命週期,{}內的變量出了{},即不可訪問;
-
構造程式碼塊(類中方法外):每建立依次物件就會執行一次,優先於構造方法執行;
-
靜態程式碼塊(類中方法外,static修飾):隨著類的載入而載入,且只執行一次。作用為給類進行初始化,一般用來載入驅動。
注:static{ } 優先於main方法執行。
class Fu {
static {
System.out.println("靜態程式碼塊Fu");
}
{
System.out.println("構造程式碼塊Fu");
}
public Fu() {
System.out.println("構造方法Fu");
}
}
class Zi {
static {
System.out.println("靜態程式碼塊Zi");
}
{
System.out.println("構造程式碼塊Zi");
}
public Zi() {
//預設super(); 見下一知識點
System.out.println("構造方法Zi");
}
}
執行 Zi z = new Zi(); 得結果如下:
靜態程式碼塊Fu
靜態程式碼塊Zi
構造程式碼塊Fu
構造方法Fu
構造程式碼塊Zi
構造方法Zi
說明:1.類載入時載入靜態程式碼塊;2.根據分層初始化規則,先載入父類構造方法,但發現有構造程式碼塊,故父構造程式碼塊->父構造方法;然後子構造程式碼塊->子構造方法
2.super和this的注意點
1.this呼叫父類成員:this.xx呼叫時,本類中沒有xx成員方法或者xx成員變數時,呼叫父類的xx成員方法或者xx成員變數。
2.構造方法預設super():任何類的構造方法預設含"super();",最高階類為Object;
3.過載(overload)和重寫(override)
過載和重寫的比較
—— | 過載(overload) | 重寫(override) |
---|---|---|
程式碼位置 | 類內 | 父類和子類之間 |
方法宣告 | 方法名相同,引數不同(引數名;引數型別;引數順序),方法體不同;與返回值無關 | 子類方法名和父類方法名完全相同,方法體不同; |
場景 | 不同引數不同調用結果,如:求圖形面積,三角形兩個引數,梯形三個引數 | 子類需要父類的功能,而功能主體子類有自己特有的內容時 |
補充 | 重寫後,將用父類的方法時用 “super.方法()” 呼叫 |
一直重寫過載傻傻分不清,記錄下來方便以後溫習。
4.final修飾符
final指的是最終的。
- 被final修飾的變數,變成常量,只能被賦值一次。
----常和public static一起用,實現“類名.被final修飾的變數”呼叫模式- 被final修飾的方法,不能被重寫
- 被final修飾的類,不能被繼承
注意點:
基本型別:值不能被改變
引用型別:地址值不能被改變(不能再次引用物件),但物件中的屬性可以改變
對此驗證,假設有如下類:
final class Final {
int x=1;
public void print() {
System.out.println(x);
}
}
呼叫可得:
Final f = new Final();
f = new Final(); //報錯
f.x = 2; //沒問題
f.print(); //得到輸出:2
5.多型中的成員訪問特點
多型的前提是:1.有繼承關係;2.有方法重寫;3.要有上轉型
- 只有動態成員方法動態繫結,即編譯看左邊(父類),編譯看右邊(子類);
- 其他編譯執行都看左邊(父類)。
成員變數的呼叫
- 編譯看左邊(父類),執行看左邊(父類)
class Demo_Polymorphic {
public static void main(String[] args) {
Father f = new Son();
System.out.println(f.num);
Son s = new Son();
System.out.println(s.num);
}
class Father {
int num = 10;
}
class Son extends Father {
int num = 20;
}
這段程式的記憶體圖如下:
結論:
Father 型別的變數智慧看到super 部分的成員,即得num=10;
Son型別的變數可以看到this範圍內的所有成員,依據就近原則,取得num=20.
成員方法的呼叫
- 編譯看左邊(父類),執行看右邊(子類)
- 即動態繫結
class Demo_Polymorphic {
public static void main(String[] args) {
Father f = new Son();
f.print();
}
}
class Father {
int num = 10;
public void print(){ //父類沒有被呼叫方法時,編譯將通不過
System.out.println(num);
}
}
class Son extends Father {
int num = 20;
public void print(){
System.out.println(num);
}
}
編譯時看父類有沒有print方法,記憶體圖如下:
執行時看子類有沒有print方法,記憶體圖如下:
靜態成員方法的呼叫
- 編譯看左邊(父類),執行看左邊(父類)
不存在 “動態繫結”
Father f = new Son();
f.staticMethod(); //由於靜態,相當於 Father.staticMathod();
6.多型+instanceof關鍵字
上轉型和下轉型
上轉型:父類引用指向子類物件
下轉型:將上轉型物件轉回子類物件
多型適用場景
用作引數的時候用多型最佳,這樣擴充套件性好
開發中很少在建立物件是用父類引用指向子類物件,直接建立子類物件,多餘且不能訪問子類特有屬性和行為
舉個小例子:
class AnimalGames {
public static void main(String[] args) {
movement(new Cat());
movement(new Pig());
}
//多一種動物不需要多寫movement方法,而是增加方法內邏輯分支,拓展性強。
//引數上轉型,相當於Animal a = new Cat();
public static void movement(Animal a){
if(a instanceof Cat){ //判斷引用a是否輸入Cat資料型別
Cat c = (Cat)a; //此處下轉型,若只用到父類共性方法,無需下轉
c.eat();
c.catchMouse(); //子類特有,下轉後才能呼叫
}else if(a instanceof Pig){
Pig p = (Pig)a;
p.eat();
p.sleep();
}
}
}
class Animal {
public void eat(){
System.out.println("動物吃");
}
}
class Cat extends Animal {
public void eat(){
System.out.println("貓吃魚");
}
public void catchMouse(){
System.out.println("貓抓老鼠");
}
}
class Pig extends Animal {
public void eat(){
System.out.println("豬吃飼料");
}
public void sleep(){
System.out.println("豬睡懶覺");
}
}
輸出結果為:
貓吃魚
貓抓老鼠
豬吃飼料
豬睡懶覺
心得:
總覺得這段時間將會是退休前最空閒的一段時間了。
希望能夠在這段時間好好地沉下心來鑽一鑽技術基礎,更重要的是希望能夠更沉得下心,好好歸零,做好規劃,飽含憧憬和期待地走向下一程!
定個目標,勤寫部落格,保持學習慣性。
另外不得不說markdown真是好用,深得我心~