【JAVA】筆記(5)--- final;抽象方法;抽象類;介面;解析繼承,關聯,與實現;

猿頭猿腦的王狗蛋發表於2021-11-13

final:

1.理解:凡是final修飾的東西都具有了不變的特性;

2.修飾物件:

1)final+類--->類無法被繼承;

2)final+方法--->方法無法被覆蓋;

3)final+變數--->只能被賦值一次;

eg:被 final 修飾的引用,由於只能被賦值一次,所以其儲存的地址不變,所以它的指向也就不會改變,但不代表其指向的物件內部的資料不會改變;

注意:

被 final 修飾的變數為例項變數時,必須手動初始化(否則報錯),不能系統自動賦值了;

final 修飾的靜態變數一般與static聯合使用,稱為常量,eg:public static final double PI = 3.1415926 ;

抽象方法:

1.概念:被 abstract 修飾的方法,無方法體(  { } 也不能寫 ),而且不以 ” } “結尾,以 ” ;“ 結尾;

2.格式:public abstract void fangFa ( ) ;

3.注意:抽象方法可以有引數列表;

              抽象方法被重寫時,abstract 要去掉;引數列表不能改變;並且加上方法體;

抽象類與介面:

1.抽象類:

1)概念:將類之間的共同特徵提取出來,抽象為一個類,這種類就叫抽象類;

2)格式:abstract + class + 類名

3)抽象類可以被繼承,子類可以為抽象類,也可以不是,但如果不是抽象類,必須對抽象類(父類)中的所有抽象方法進行覆蓋;

4)注意:抽象類無法例項化為物件;

              若抽象之間有共同特徵,也可將其進一步抽象為一個抽象類;

              final 與 abstract 不能聯合修飾一個東西;

              抽象類中也有構造方法,意義:給子類使用;

              抽象類中可以有普通方法,也可以有抽象方法,但是抽象方法必須出現在抽象類中,不能出現在非抽象類中;

2.介面:

1)定義: interface + 介面名   

2)特性:

  介面支援多繼承;

  介面中所有的方法都是預設被 public abstract 修飾的,且可以省略,eg: 返回值型別 + 方法名(引數列表);

  介面中的所有量都是預設被 public static final 修飾的,且可以省略,所以介面中只有常量,沒有變數;

  介面被繼承不用 extends 用 implements(實現);

  介面的完全抽象的性質,可以進一步使程式的耦合性降低,擴充性提高;

3)注意;

extends 可以與 implements 共存,extends 在前,implements 在後;

介面由於是完全抽象的,所以被實現時,也與抽象類遵循相同的規則,若子類不為抽象類,則需要對介面中的所有抽象方法都進行方法覆蓋

分析原因:因為繼承與實現都相當於將類體中或介面內的程式碼複製貼上到子類中,所以遵循” 抽象方法只能出現在 抽象類 / 介面中 “的原則,必須要對 抽象/介面 中的所有抽象方法進行方法覆蓋-->即將抽象方法轉化為普通方法 ;

3.抽象類與介面的區別;

1)構造方法:前有,後無;

2)繼承機制:前單繼承,後多繼承(interfaces 後可以加多個介面,extends 後只可以加一個類)

3)抽象類中的方法與量都無限制,介面中的方法只能是抽象方法,量只能是常量;

解析繼承,關聯,與實現:

1.繼承:” is a “,   例如:猴子是一種動物,則 猴子 extends 動物;

  ---使猴子繼承動物該有的特性

2.關聯:” has b “,例如:我有一雙鞋類,則 class 我 {   鞋  鞋 ;  }

  ---將鞋類作為一種屬性寫在 我類 中,因為我穿鞋呀,所以利用關聯來使” 我 擁有了 鞋“  

3.實現:” like c “,例如:廚師像一個選單一樣,則  class  廚師  interfaces  選單  {  重寫選單中的方法  }

  ---對於” 顧客利用選單來點菜 “的機制來說,廚師類來實現介面,顧客來呼叫介面

輔助理解程式碼:

public class 顧客點西式柿子炒雞蛋 {
    public static void main(String[] args) {
        //利用多型機制建立美國廚師物件
        FoodMenu cooker=new AmericanCooker();
        //呼叫構造方法使 顧客拿到了選單,並將物件美國廚師傳到了選單中
        Customer customer=new Customer(cooker);
        //呼叫顧客中的點菜方法(顧客中的點菜方法呼叫選單中的柿子炒雞蛋方法,此時選單中的方法已被美國廚師中的方法覆蓋了,所以顧客吃到的是西式柿子炒雞蛋)
        customer.order();
    }
}
interface FoodMenu{
    void shiZiChaoJiDan();
}
class ChinaCooker implements FoodMenu{
    public void shiZiChaoJiDan(){
        System.out.println("中國師傅做的柿子炒雞蛋!");
    }
}
class AmericanCooker implements FoodMenu{
    public void shiZiChaoJiDan(){
        System.out.println("美國師傅做的柿子炒雞蛋!");
    }
}
class Customer{
    private FoodMenu foodMenu;
    public Customer() {
    }
    public Customer(FoodMenu foodMenu) {
        this.foodMenu = foodMenu;
    }
    public FoodMenu getFoodMenu() {
        return foodMenu;
    }
    public void setFoodMenu(FoodMenu foodMenu) {
        this.foodMenu = foodMenu;
    }
    public void order(){
        foodMenu.shiZiChaoJiDan();
    }
}

執行結果:

美國師傅做的柿子炒雞蛋!

Process finished with exit code 0

程式碼解析;

1.選單是一個介面(選單上有一個抽象的照片:柿子炒雞蛋);

2.顧客面向選單點菜,呼叫介面;

3.後臺的廚師負責把柿子炒雞蛋做好,是介面的是實現者;

4.介面作用:這個飯館的選單,讓顧客和後廚解耦合了,顧客不用找後廚,後廚不用找顧客,他們之間完全依靠這個抽象的選單溝通;

5.總結:面向介面程式設計,可以降低程式的耦合度,提高程式的擴充力;介面的使用離不開多型機制(介面+多型才可以達到降低耦合度);任何一個介面都有呼叫者和實現者,介面可以將呼叫者與實現者解耦合,呼叫者面向介面呼叫,實現者面向介面編寫實現;

隨筆:

Java語言中凡是沒有方法體的方法都是抽象方法?

錯,Object 類中就有很多方法都沒有方法體,都是以 ” ;“ 結尾的,但他們 都不是抽象方法,eg:public native int hashCode( ) ;

此方法底層是呼叫了C++寫的動態連結庫程式,native 表示呼叫 JVM 本地程式;


由於博主目前只是一隻猿寶寶,所以有些地方可能說的有些片面,若前輩們能夠指點一二就更好了      (~ ̄(OO) ̄)ブ

相關文章