類的繼承結構中,越往上的類越具有通用性,也就越抽象。當它抽象到一定程度,就變成概念成框架,不能再產生實例化的對象了。例如“交通工具”,就無法用它來產生一個實例。
對應這一現象,Java中提供了抽象類,它只能作爲父類,不能實例化。定義抽象類的作用是將一類對象的共同特點抽象出來,成爲代表該類共同特性的抽象概念,其後在描述某一具體對象時,只要添加與其他子類對象的不同之處,而不需要重複類的共同特性。這樣就使得程序概念層次分明,開發更高效。與抽象類緊密相連的是抽象方法一它總是用在抽象類或接口中。
一、抽象類的定義
被關鍵字“abstract”修飾的類,爲抽象類。(而且,abstract只能修飾類和方法)
abstract class className{
類體;
}
在抽象類中,可以有0個或者多個抽象方法,也可以有普通的實例方法和靜態方法,還可以有其他的成員變量和構造方法。如果類中沒有任何形式的抽象方法,那麼可以由程序員決定是否將類聲明成abstract類型,但是隻要是下面這些情況之一,那類必定爲抽象類,必須加上abstract修飾。
- 類中明確聲明有abstract方法的。
- 類是抽象類繼承下來的,而且沒有實現父類中全部的抽象方法。
- 類實現了一個接口,但沒有將其中所有的抽象方法實現。
抽象類不一定有抽象方法,有抽象方法的類一定是抽象類或者是接口。(這點要銘記,有些文章說含有抽象方法的類就是抽象類,這個是不準確的
)
那麼什麼是抽象方法呢?
二、抽象方法的聲明
抽象方法:使用abstract關鍵字定義的方法,抽象方法沒有具體的方法體;抽象類必須也要用abstract關鍵字定義。
抽象方法是一種只有方法聲明面沒有方法體定義的特殊方法。它的聲明部分和一般方法並
沒有太大的區別,也有訪問權限、返回值類型等,只是需要在前面加上一個關鍵字“abstract”。通常的形式如下
abstract 訪問權限 返回類型 方法名 ([參數列表]);
特持別注意它的最後有一個分號“;”,而沒有方法體的括號“{ }”。
例如下面就是一個合法的抽象方法。
abstract protected void eat();
而下面這個,雖然方法體爲空,但它不是一個合法的抽象方法。
abstract protected void eat() { }
聲明抽象方法時有以下幾個限制,具體原理文章後面會講到
- 構造方法不能聲明爲 abstract
- 靜態方法不能聲明爲 abstract
- privale方法不能聲明爲 abstraet
- final方法不能聲明爲 abstract
- 抽象方法只能出現在抽象類或接口中
三、抽象類的特點
1.抽象類和抽象方法必須用abstract關鍵字修飾
abstract class 類名 {}
public abstract void 方法名();
2.抽象類不一定有抽象方法,有抽象方法的類一定是抽象類或者是接口(這點上面講過,是個易錯點)
3.抽象類不能實例化,那麼抽象類如何實例化
抽象類如果可以實例化的話,那麼就可以調用類中的抽象方法,很明顯調用抽象方法是沒有意義的,所以抽象類不能實例化,如何非要實例化,那就按照多態的方式,由具體的子類實例化。(其實這也是多態的一種,抽象類多態,不能算抽象類實例化)
public class Demo1_Abstract {
public static void main(String[] args) {
//Animal a = new Animal(); //錯誤: Animal是抽象的; 無法實例化
Animal a = new Cat(); //父類引用指向子類對象
a.eat();
}
}
abstract class Animal { //抽象類
public abstract void eat(); //抽象方法
}
class Cat extends Animal {
public void eat() {
System.out.println("貓喫魚");
}
}
運行結果:
4.抽象類的子類
要麼是抽象類
要麼重寫抽象類中的所有抽象方法
補充說明
四、抽象類的成員特點
抽象類的成員特點:
- 成員變量:既可以是變量,也可以是常量。(abstract是否可以修飾成員變量?不能修飾成員變量)
- 構造方法:有,用於子類訪問父類數據的初始化。
- 成員方法:既可以是抽象的,也可以是非抽象的。
abstract class Demo {
int num1 = 10; //定義了變量
final int num2 = 20; //定義了常量
public Demo(){} //構造方法
public void print() {
System.out.println("hello");
}
public abstract void method(); //既有非抽象方法又有抽象方法
}
class Test extends Demo {
public void method() {
System.out.println("world");
}
}
抽象類的成員方法特性:
- 抽象方法:強制要求子類做的事情。
- 非抽象方法:子類繼承的事情,提高代碼複用性。
五、抽象類的一些問題解答
1、一個抽象類如果沒有抽象方法,可不可以定義爲抽象類?如果可以,有什麼意義?
可以,這麼做目的只有一個,就是不讓其他類創建本類對象,交給子類完成
2.構造方法爲什麼不能聲明爲 abstract?
構造方法不能被繼承,一個抽象的構造方法將永遠不會被實現,所以它也不能聲明爲abstract的。
3.abstract不能和哪些關鍵字共存?
1.abstract和static
被abstract修飾的方法沒有方法體
被static修飾的可以用類名.調用,但是類名.調用抽象方法是沒有意義的
2.abstract和final
被abstract修飾的方法強制子類重寫
被final修飾的不讓子類重寫,所以他倆是矛盾
3.abstract和private
被abstract修飾的是爲了讓子類看到並強制重寫
被private修飾不讓子類訪問,所以他倆是矛盾的
測試如下
abstract class Demo {
//public static abstract void print(); //錯誤: 非法的修飾符組合: abstract和static
//public final abstract void print(); //錯誤: 非法的修飾符組合: abstract和final
private abstract void print(); //錯誤: 非法的修飾符組合: abstract和private
}