在java中用abstract關鍵字聲明的類稱為抽象類。 它可以有抽象和非抽象方法(帶主體的方法)。
在學習java抽象類之前,先來瞭解java中的抽象。
Java中的抽象
抽象是隱藏實現細節並僅向用戶顯示功能的過程。
另一種方式,它只向用戶顯示重要的事情,並隱藏內部詳細資訊,例如:發送短信,只需輸入文本併發送消息。您也不需要知道有關郵件傳遞的內部處理過程。
抽象可以讓你專注於對象做什麼(實現的功能),而不是它如何做。
實現抽象的方法
在java中有兩種實現抽象的方法,它們分別是:
- 抽象類(部分)
- 介面 (完全)
1. Java中的抽象類
使用 abstract關鍵字聲明的類被稱為抽象類。需要擴展和實現它的方法。 它不能被實例化。
抽象類示例
abstract class A{}
抽象方法
一個被聲明為 abstract 而沒有實現的方法稱為抽象方法。
抽象方法示例
abstract void printStatus();//no body and abstract
具有抽象方法的抽象類的示例
在這個例子中,Bike是一個抽象類,只包含一個抽象方法:run()。 它由 Honda 類提供實現。
abstract class Bike {
    abstract void run();
}
class Honda4 extends Bike {
    void run() {// run 方法的實現
        System.out.println("running safely..");
    }
    public static void main(String args[]) {
        Bike obj = new Honda4();
        obj.run();
    }
}
上面示例中的代碼執行結果如下 -
running safely..
理解抽象類的真實應用場景
在這個例子中,Shape是一個抽象類,它的實現分別由Rectangle和Circle類提供。 大多數情況下,我們不知道實現類(即對最終用戶隱藏),實現類的對象由工廠方法提供。
工廠方法是用於返回類的實例的方法。 稍後我們將在下一節中瞭解和學習工廠方法。
在這個例子中,創建Rectangle類的實例,Rectangle類的draw()方法將被調用。創建一個類檔:TestAbstraction1.java ,它的代碼如下所示 -
abstract class Shape {
    abstract void draw();
}
// In real scenario, implementation is provided by others i.e. unknown by end
// user
class Rectangle extends Shape {
    void draw() {
        System.out.println("drawing rectangle");
    }
}
class Circle1 extends Shape {
    void draw() {
        System.out.println("drawing circle");
    }
}
// In real scenario, method is called by programmer or user
class TestAbstraction1 {
    public static void main(String args[]) {
        Shape s = new Circle1();// In real scenario, object is provided through
                                // method e.g. getShape() method
        s.draw();
    }
}
上面代碼執行結果如下 -
drawing circle
在java中抽象類的另一個例子
創建一個Java檔:TestBank.java,代碼如下所示 -
abstract class Bank {
    abstract int getRateOfInterest();
}
class SBI extends Bank {
    int getRateOfInterest() {
        return 7;
    }
}
class PNB extends Bank {
    int getRateOfInterest() {
        return 8;
    }
}
class TestBank {
    public static void main(String args[]) {
        Bank b;
        b = new SBI();
        System.out.println("Rate of Interest is: " + b.getRateOfInterest() + " %");
        b = new PNB();
        System.out.println("Rate of Interest is: " + b.getRateOfInterest() + " %");
    }
}
上面代碼執行結果如下 -
Rate of Interest is: 7 %
Rate of Interest is: 8 %
具有構造函數,數據成員,方法等的抽象類
抽象類可以有數據成員,抽象方法,方法體,構造函數甚至main()方法。創建一個Java檔:TestAbstraction2.java,代碼如下所示 -
//example of abstract class that have method body
abstract class Bike {
    Bike() {
        System.out.println("bike is created");
    }
    abstract void run();
    void changeGear() {
        System.out.println("gear changed");
    }
}
class Honda extends Bike {
    void run() {
        System.out.println("running safely..");
    }
}
class TestAbstraction2 {
    public static void main(String args[]) {
        Bike obj = new Honda();
        obj.run();
        obj.changeGear();
    }
}
上面代碼執行結果如下 -
bike is created
running safely..
gear changed
規則:如果在類中有任何抽象方法,那個類必須聲明為抽象的。
class Bike12{
    abstract void run();
}
上面的 Bike12 是無法編譯通過的。
規則:如果你擴展任何具有抽象方法的抽象類,必須提供方法的實現或使這個類抽象化。
抽象類的另一個真實場景
抽象類也可以用於提供介面的一些實現。 在這種情況下,終端用戶可能不會被強制覆蓋介面的所有方法。
注意:如果您是初學者到Java,請跳過此示例先學習介面(interface)。
interface A {
    void a();
    void b();
    void c();
    void d();
}
abstract class B implements A {
    public void c() {
        System.out.println("I am C");
    }
}
class M extends B {
    public void a() {
        System.out.println("I am a");
    }
    public void b() {
        System.out.println("I am b");
    }
    public void d() {
        System.out.println("I am d");
    }
}
class Test5 {
    public static void main(String args[]) {
        A a = new M();
        a.a();
        a.b();
        a.c();
        a.d();
    }
}
上面代碼執行結果如下 -
I am a
I am b
I am c
I am d
