首頁 > 軟體

詳解JavaSE中抽象類與介面的定義及使用

2022-07-01 14:00:18

一、抽象類

1、抽象類定義

1、什麼是抽象類?

類和類之間具有共同特徵,將這些共同特徵提取出來,形成的就是抽象類。

類到物件是範例化,物件到類是抽象。

抽象類無法範例化,無法建立物件。抽象類是類和類之間有共同特徵,將這些具有共同特徵的類再進一步抽象,就形成了抽象類。由於類本身是不存在的,所以抽象類無法建立物件,即無法範例化。

2、抽象類屬於什麼型別?

抽象類也屬於參照資料型別。

3、抽象類的語法:

[修飾符列表] abstract class 類名{
        類體;
}

4、抽象類是無法範例化的,無法建立物件,因此抽象類是用來被子類繼承的。

抽象類的子類還可以是抽象類

//銀行賬戶類
abstract class Account{
}

//信用卡類,子類繼承抽象類,子類可以範例化物件
class CreditAccount extends Account{
}

//抽象類的子類還可以是抽象類
abstract class Credit extends Account{
}

5、抽象類雖然無法範例化,但是抽象類有構造方法,這個構造方法是為子類提供的

2、抽象方法

抽象方法表示沒有實現的方法,沒有方法體的方法。

抽象方法的特點:

1、沒有方法體,以分好結尾

2、前面修飾符列表當中有abstract關鍵字

例如:

public abstract void doSome;
  • 抽象類當中不一定有抽象方法,但是有抽象方法的類一定是抽象類。
  • 抽象類當中可以有抽象方法也可以有非抽象方法。
  • 抽象方法必須出現在抽象類當中,一個非抽象類繼承抽象類,必須將抽象類當中的抽象方法進行實現。
abstract class Animal{
    public abstract void move(); 
}

class Bird extends Animal{
    //將抽象類當中的抽象方法進行重寫
    public void move(){};
}

上面當中,如果Bird類是抽象的話,則抽象方法也可以不重寫。

public class Test01 {
    public static void main(String[] args) {
        //使用多型,父類別型參照指向子型別物件
        //Bird不是抽象類,可以建立物件,向上轉型
        Animal a=new Bird();//面向抽象程式設計
        a.move();
        //在編譯的時候,a會檢查Animal當中的move方法
        //在執行的時候,a會使用Bird當中的move方法
    }
}

判斷題:java語言當中凡是沒有方法體的方法都是抽象方法(錯)

Object類當中有很多方法都沒有方法體,都是以分好結尾的,但是他們都不是抽象方法,例如:

public native int hashCode();

這個方法底層呼叫了C++寫的動態連結庫程式。前面修飾符列表中沒有abstract。有一個native,表示呼叫JVM原生的程式。

二、介面

1、介面定義

1、介面也是一種參照資料型別,編譯之後也是一個class位元組碼檔案。

2、介面是完全抽象的。(抽象類是半抽象的)或者說介面是特殊的抽象類。

3、介面的定義:

[修飾符列表]  interface 介面名{
}

4、介面支援多繼承,一個介面可以繼承多個介面。

//定義介面
interface A{
}

interface B{
}
//支援多繼承
interface C extends A,B{
}

5、介面當中只包含兩部分內容,一部分是:常數,一部分是:抽象方法。

//我的數學介面
interface MyMath{
    public abstract int sum(int a,int b);
}

6、介面當中所有的元素都是public修飾的。

7、介面當中的抽象方法定義時:public abstract修飾符可以省略。

8、介面當中的方法都是抽象方法,所有介面當中的方法不能有方法體。

9、介面當中的方法不能有大括號,因為大括號就是方法體,而抽象方法不能有方法體。

10、介面當中常數的修飾符:public static final可以省略。

11、常數不能重新賦值。

interface MyMath{
    double PI=3.1415926;
    //PI是常數
    int sub(int a,int b);//相減的抽象方法
    int sum(int a,int b);//相加的抽象方法
}

2、類實現介面

介面的基礎語法:

1、類和類之間叫做繼承,類和介面之間叫做實現。(其實仍然可以將實現看成是繼承)

  • 繼承使用extends關鍵字完成
  • 實現使用implements完成
  • 當一個非抽象類實現介面的話,必須將介面當中所有的抽象方法全部實現。
interface MyMath{
    double PI=3.1415926;
    //PI是常數
    int sub(int a,int b);//相減的抽象方法
    int sum(int a,int b);//相加的抽象方法
}

class My implements MyMath{
    public int sub(int x,int y){
        return x-y;
    }
    public int sum(int x,int y){
        return x+y;
    }
}

介面和介面之間支援多繼承,一個類也可以同時實現多個介面。

這種機制彌補了java當中類與類之間只支援單繼承的缺陷。

經過測試,介面和介面之間在進行強制型別轉換的時候,沒有繼承關係,也可以強轉。但是注意:在執行時可能會出現ClassCastException異常。

public class Test04 {
    public static void main(String[] args) {
        M m=new E();
        K k=(K)m;
    }
}
interface K{
}
interface M{
}
class E implements M{
}

最終實際上和之前一樣,需要加instanceof運運算元進行判斷。

這句話不適合在介面當中:無論向上轉型還是向下轉型,兩種型別之間必須要有繼承關係,沒有繼承關係,則編譯器會報錯。

上面的程式碼更改如下:

        if(m instanceof K){
            K k=(K)m;  //判斷,否則會出現異常         
        }

3、介面與多型聯合

public class Test02 {
    public static void main(String[] args) {
        MyMath m=new My();
        //面向介面程式設計(呼叫介面裡面的方法
        int result=m.sub(10,20);
        System.out.println(result);
        int result2=m.sum(1,3);
        System.out.println(result2);
    }
}

//我的數學介面
interface MyMath{
    double PI=3.1415926;
    //PI是常數
    int sub(int a,int b);//相減的抽象方法
    int sum(int a,int b);//相加的抽象方法
}

class My implements MyMath{
    public int sub(int x,int y){
        return x-y;
    }
    public int sum(int x,int y){
        return x+y;
    }
}

4、extends和implements

問題:繼承和實現都存在的話,程式碼應該怎麼寫?

如果同時出現繼承和實現的話,繼承的關鍵字在前面,實現的關鍵字在後面。

介面通常提取的是行為動作。

class Cat extends Animal1 implements Flyable{    
}
public class Test04 {
    public static void main(String[] args) {
        Flyable f=new Cat();//多型
        f.fly();
        Flyable f1=new Pig();
        f1.fly();
    }
}

//動物類:父類別
class Animal1{
}
//可飛翔的介面
interface Flyable{
    void fly();
}

//動物類子類:貓類
//flybale是一個介面,即一對翅膀,通過介面插到貓身上,讓貓可以飛翔
class Cat extends Animal1 implements Flyable{
    public void fly(){
        System.out.println("貓貓起飛!");
    }
}

//動物類子類:蛇類
//如果不想讓蛇飛,就不實現flyable介面
//沒有實現這個介面就表示沒有翅膀,那肯定不能飛翔
class Snack extends Animal1{
}

//動物類子類:豬類,想讓豬飛,插介面
class Pig extends Animal1 implements Flyable{
    public void fly(){
        System.out.println("豬豬起飛!");
    }
}

5、介面在開發當中的作用

介面在開發當中的作用,類似於多型在開發當中的作用。

多型:面向抽象程式設計,不面向具體程式設計,降低程式的耦合度,提高程式的擴充套件力。

面向抽象程式設計可以修改為:面向介面程式設計。因為有了介面就有了可插拔。可插拔表示擴充套件能力強,不是焊接死的。例如:主機板和記憶體條之間有插槽,這個插槽就是介面,記憶體條壞了,可以重新買一個換,這就是高擴充套件性和低耦合度。

實現一個選單介面:

  1. 中午去飯館吃飯,這個過程當中有介面,介面是抽象的。
  2. 選單是一個介面。(選單上面有一個抽象的照片:西紅柿炒雞蛋)
  3. 顧客面向選單點菜,呼叫介面。
  4. 後臺的初始負責把西紅柿雞蛋做好,是介面的實現者。
  5. 這個選單介面的作用:讓顧客和廚師解耦合,顧客不用找後廚,後廚不用找顧客,他們之間完全依靠這個抽象的選單進行溝通。符合OCP開發原則。

顧客有一個選單 Customer has a FoodMenu,凡是能夠使用has a 來描述的,統一以屬性的方式存在

Cat is a Animal 凡是滿足 is a 的表示都可以設定為繼承。

西餐廚師類:

//西餐廚師實現選單上面的菜
public class AmericanCooker implements FoodMenu{
    public void xiHongShiJidan(){
        System.out.println("西餐中的西紅柿炒雞蛋");
    }
    public void yuXiangRouSi(){
        System.out.println("西餐中的魚香肉絲");
    }
}

中餐廚師類:

//中餐廚師實現選單上面的菜。廚師是介面的實現者。
public class ChinaCooker implements FoodMenu{
    public void xiHongShiJidan(){
        System.out.println("中餐中的西紅柿炒雞蛋");
    }
    public void yuXiangRouSi(){
        System.out.println("中餐中的魚香肉絲");
    }
}

顧客類:

public class Customer{
    //面向介面程式設計
    private FoodMenu foodmenu;//私有化體現封裝性,則要提供set和get方法
    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(){
        //方法一:使用get方法拿到選單
        FoodMenu f=this.getFoodmenu();
        //方法二:直接使用foodmenu,因為私有的屬性可以在本類當中使用
        foodmenu.xiHongShiJidan();
        foodmenu.yuXiangRouSi();
    }
}

選單類:

public interface FoodMenu {
    void xiHongShiJidan();
    void yuXiangRouSi();
}

測試類:

public class Test {
    public static void main(String[] args) {
        //建立廚師物件(多型)
        FoodMenu menu1=new ChinaCooker();
        FoodMenu menu2=new AmericanCooker();
        //建立顧客物件
        Customer m1=new Customer(menu1);
        Customer m2=new Customer(menu2);
        //顧客點菜
        m1.order();
        m2.order();

​​​​​​​    }
}

任何一個介面都有呼叫者和實現者,介面可以將呼叫者和實現者解耦合。以後的大專案開發,一般都是將專案分離成一個一個的模組,模組之間採用介面銜接,降低耦合度。

6、is has like

1.is a :Cat is an Animal.(貓是一個動物)

凡是滿足is a的就表示繼承關係。

2.has a:He has a pen.(他有一隻筆)

  • 凡是能夠滿足has a 關係的表示關聯關係。
  • 關聯關係通常以“屬性”的形式存在。

3.like a :Cooker like a menu.(廚師就像一個選單)

  • 凡是滿足like a 關係的表示實現關係。
  • 實現關係通常是類實現介面。

7、抽象類與介面

抽象類與介面的區別:

  • 抽象類是半抽象的,介面是完全抽象的。
  • 抽象類中有構造方法,介面當中沒有構造方法。
  • 介面和介面之間支援多繼承,類和類之間只支援單繼承。
  • 一個類可以同時實現多個介面,一個抽象類只能繼承一個類(單繼承)。
  • 介面都在只允許出現常數和抽象方法。

到此這篇關於詳解JavaSE中抽象類與介面的定義及使用的文章就介紹到這了,更多相關JavaSE抽象類 介面內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com