java中的抽象類與介面

~扶蘇~發表於2020-11-13

一、抽象類

1.抽象類的含義

在瞭解抽象類之前我們要先知道什麼是普通類。普通類具有完整的類功能,不但可以直接產生例項化物件,而且在普通類中可以包含有構造方法、普通方法、static(靜態)方法、常量和變數等內容。而抽象類是指在普通類的結構裡面增加抽象方法的組成部分。
那麼什麼叫抽象方法呢?在所有的普通方法上面都會有一個“{}”,這個表示方法體,有方法體的方法一定可以被物件直接使用。而抽象方法,是指沒有方法體的方法,同時抽象方法還必須使用關鍵字abstract做修飾。而擁有抽象方法的類就是抽象類,抽象類要使用abstract關鍵字宣告。
**注意:abstract修飾符
1.abstract修飾的類為抽象類,此類不能有物件,(無法對此類進行例項化,說白了就是不能new);
2.abstract修飾的方法為抽象方法,此方法不能有方法體(就是什麼內容不能有);
範例:定義一個抽象類

abstract class student{//定義一個抽象類	
	public void sleep(){//普通方法
		System.out.println("我喜歡學習");
	}	
	public abstract void play();//抽象方法,沒有方法體,有abstract關鍵字做修飾	
}

2.抽象類的使用原則

在這裡我們先看一個例子:

package Work;
abstract class Student{//定義一個抽象類
    public void sleep(){//普通方法
        System.out.println("學生喜歡學習");
    }
    public abstract void paly();//抽象方法,沒有方法體,有abstract關鍵字做修飾
}
public class Work11_111 {
    public static void main(String[] args) {
        Student Me= new Student();
    }
}

執行結果:
在這裡插入圖片描述
由此可知,Student是抽象的,無法直接進行例項化操作。什麼是例項化?當一個類例項化之後,就意味著這個物件可以呼叫類中的屬性或者方法,但在抽象類中存在抽象方法,而抽象方法沒有方法體,沒有方法體就無法進行呼叫。既然無法進行方法呼叫的話,自然無法產生例項化物件。
進而·可以得到抽象類的使用原則:
(1)抽象類不能直接使用,需要子類去實現抽象類,然後使用其子類的例項。(需要依靠子類採用向上轉型的方式處理)
(2)抽象方法必須為public或者protected(因為如果為private,則不能被子類繼承,子類便無法實現該方法),預設情況下預設為public;
(3)抽象類必須有子類,使用extends繼承,一個子類只能繼承一個抽象類;
(4)子類(如果不是抽象類)則必須覆寫抽象類之中的全部抽象方法(如果子類沒有實現父類的抽象方法,則必須將子類也定義為為abstract類。);
*注:
在這裡插入圖片描述
重寫範例:

package Work;
abstract class Student{//定義一個抽象類
  public void sleep(){//普通方法
      System.out.println("學生喜歡學習");
  }
  public abstract void paly();//抽象方法,沒有方法體,有abstract關鍵字做修飾
}
class People extends Student{
  @Override
  public void paly() {
      System.out.println("我喜歡學習");
  }
}
public class Work11_111 {
  public static void main(String[] args) {
      Student Me= new People();
      Me.paly();
      Me.sleep();
  }
}

執行結果如下:

我喜歡學習
學生喜歡學習

3.抽象類使用限制

1)抽象類不可以用final宣告:因為抽象類必須有子類,而final定義的類不能有
子類。
2)抽象類中存在有構造方法:抽象類裡會存在一些屬性,所以抽象類中一定存在構造方法,其存在目的是為了屬性的初始化。並且子類物件例項化的時候,依然滿足先執行父類構造,再執行子類構造的順序。
3)抽象類能否使用static宣告?
先看一個關於外部抽象類的範例:

package Work;
 static abstract class Student{//定義一個抽象類
    public void sleep(){//普通方法
        System.out.println("學生喜歡學習");
    }
    public abstract void paly();//抽象方法,沒有方法體,有abstract關鍵字做修飾
}
class People extends Student{
    @Override
    public void paly() {
        System.out.println("我喜歡學習");
    }
}
public class Work11_111 {
    public static void main(String[] args) {
        Student Me= new People();
        Me.paly();
        Me.sleep();
    }
}

執行結果:
在這裡插入圖片描述
再看一個關於內部抽象類:

package Work;
abstract class Student{//定義一個抽象類
     static abstract class B{//static定義的內部類屬於外部類
         public abstract void play();
     }
     //抽象方法,沒有方法體,有abstract關鍵字做修飾
}
class People extends Student.B{
    @Override
    public void play() {
        System.out.println("我喜歡學習");
    }
}
public class Work11_111 {
    public static void main(String[] args) {
        Student.B Me= new People();
        Me.play();
    }
}

執行結果:

我喜歡學習

由此可見,外部抽象類不允許使用static宣告,而內部的抽象類執行使用static宣告。使用static宣告的內部抽象類相當於一個外部抽象類,繼承的時候使用“外部類.內部類”的形式表示類名稱。

二、介面

1.介面的含義

Java裡面由於不允許多重繼承,所以如果要實現多個類的功能,則可以通過實現多個介面來實現。介面可以看作是抽象類的變體,介面中所有的方法都是抽象的。介面通常以interface來宣告。一個類通過繼承介面的方式,從而來繼承介面的抽象方法。
我們使用interface關鍵字定義介面,一般使用介面宣告方法或常量,介面中的方法只能是宣告,不能是具體的實現,這一點和抽象類是不一樣的。介面是更高階別的抽象。介面的定義格式是:

public interface 介面名稱{
    //可以定義常量
    //方法只有方法宣告,而且是公共的。
    public void 方法名稱();
    ...
}

類要實現介面,只需要使用implements關鍵字,實現類必須要實現介面中的所有的方法

public class 實現類名 implements 介面{
    //實現介面的方法
}

2.介面的實現

(1)定義介面

示例程式碼如下:

// 定義方法的介面
public interface People {
  // 定義程式使用的常量的介面,介面中只能有常量。
  public static final double count = 1314.00;
  public static final int age = 5;
  //介面中所有的方法都沒有方法體。
  public void add(int x, int y);
  public void volume(int x,int y, int z);
}

(2)實現介面

程式碼如下:

//實現     介面
public class Student implements People {
    @Override
    public void add(int x, int y) {
    }
    @Override
    public void volume(int x, int y, int z) {
    }
}

一個類是可以實現多個介面,因為java是單繼承的,這點介面可以彌補。我們可以再定義一個介面,如下:

public interface People2 {
    public void num();
}

修改上面的實現類,要實現多個介面,可以使用逗號隔開,當然所有的介面的方法都要實現。

//實現       介面1,介面2
public class Student implements People ,People2{
    @Override
    public void add(int x, int y) {
    }
    @Override
    public void volume(int x, int y, int z) {
    }
    @Override
    public void num() {
    }
}

(3)利用介面實現計算機的四則運算

程式碼如下:

package Work;
interface Computer{
    int count(int n,int m);
}
//加法
class Add implements Computer {
    @Override
    public int count(int n, int m) {
        return n + m;
    }
}
//減法
class Sub implements Computer {
    @Override
    public int count(int n, int m) {
        return n - m;
    }
}
//除法
class Div implements Computer{
    @Override
    public int count(int n, int m) {
        if(m!=0){
            return n/m;
        }
        else {
            System.out.println("分母不能為0");
            return 0;
        }
    }
}
//乘法
class Mul implements Computer{
    @Override
    public int count(int n, int m) {
        return n*m;
    }
}
//介面是不能直接例項化的,需要定義一個實現類,將介面的引用作為example的引數,利用Realize類實現介面。
class Realize{
    public void example(Computer s,int n, int m){
        System.out.println(s.count(n,m));
    }
}
public  class TestDemo11_2 {
        public static void main (String[] args){
            Realize s=new Realize();
            s.example(new Add(),1,2);
            s.example(new Sub(),1,2);
            s.example(new Div(),4,2);
            s.example(new Mul(),1,2);
        }
}

3.介面與類的區別

  • 介面不能用於例項化物件。
  • 介面中所有的方法必須是抽象方法。
  • 介面不能包含成員變數,除了 static 和 final 變數。
  • 介面不是被類繼承了,而是要被類實現。
  • 介面支援多繼承。

4.抽象類和介面的區別

1)抽象類中的方法可以有方法體,就是能實現方法的具體功能,但是介面中的方法不行。
2)抽象類中的成員變數可以是各種型別的,而介面中的成員變數只能是 public static final 型別的。
3)介面中不能含有靜態程式碼塊以及靜態方法(用 static 修飾的方法),而抽象類是可以有靜態程式碼塊和靜態方法。
4)一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。

5.使用介面注意事項

1)不能夠new建立物件
2)如果要去建立一個介面對應的物件,則需要通過它的具體實現類, 使用implements關鍵字去實現介面 。
3) 介面被編譯之後也會產生對應的位元組碼檔案
4)介面之間也是可以相互繼承 extends
5) 介面對應是多實現 eg.class C implements A,B
6) 抽象類中設定的都是通用的方法,功能與實體都是一種"是"的關係,介面中功能與實體都是一種"有"的關係
7)介面中定義的屬性為什麼是static final的?
static 原因主要是介面的實現是多實現,為了區分不同介面當中的相同變數
final 原因是因為如果是變數,介面的存在就失去其意義,同時介面來說指的 是統一的協議,Java設計者直接規定介面中的屬性只能是public static final的。
8)介面是隱式抽象的,當宣告一個介面的時候,不必使用abstract關鍵字。
介面中每一個方法也是隱式抽象的,宣告時同樣不需要abstract關鍵字。

相關文章