Java抽象類/抽象方法定義及其特性詳解

       類的繼承結構中,越往上的類越具有通用性,也就越抽象。當它抽象到一定程度,就變成概念成框架,不能再產生實例化的對象了。例如“交通工具”,就無法用它來產生一個實例。
       對應這一現象,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.抽象類的子類

 要麼是抽象類
 要麼重寫抽象類中的所有抽象方法

補充說明
在這裏插入圖片描述

四、抽象類的成員特點

抽象類的成員特點:

  1. 成員變量:既可以是變量,也可以是常量。(abstract是否可以修飾成員變量?不能修飾成員變量)
  2. 構造方法:有,用於子類訪問父類數據的初始化。
  3. 成員方法:既可以是抽象的,也可以是非抽象的。
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.abstractstaticabstract修飾的方法沒有方法體
    被static修飾的可以用類名.調用,但是類名.調用抽象方法是沒有意義的
2.abstractfinalabstract修飾的方法強制子類重寫
    被final修飾的不讓子類重寫,所以他倆是矛盾
3.abstractprivateabstract修飾的是爲了讓子類看到並強制重寫
    被private修飾不讓子類訪問,所以他倆是矛盾的

測試如下

abstract class Demo {
	//public static abstract void print();	//錯誤: 非法的修飾符組合: abstract和static
	//public final abstract void print();	//錯誤: 非法的修飾符組合: abstract和final
	private abstract void print();			//錯誤: 非法的修飾符組合: abstract和private
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章