爲什麼會出現抽象類這種類?java
一、某些狀況下,父類只知道子類須要哪些方法,可是不知道子類如何實現這些方法,或者每一個子類對同一方法的實現都不一樣ide
二、因此容許父類定義方法時,只定義方法,可是不具體實現,定義的這種方法稱爲抽象方法,包含這種抽象方法的類,就被稱爲抽象類this
三、抽象方法:只有方法簽名,沒有方法實現的方法,抽象方法用 abstract 修飾 ,如:對象
public abstract double getHeight();
四、上面的代碼定義了一個 抽象方法:getHeight();只有方法簽名,沒有後面的方法體。blog
所以總結出抽象方法和抽象類的一些規則以下:繼承
一、抽象類和抽象方法必須用 abstract 修飾符來修飾接口
二、抽象方法不能有方法體get
三、抽象類不能被實例化,沒法使用 new 關鍵字來調用抽象類的構造器來實現實例對象,即便抽象類裏不包含抽象方法,這個類也不能被實例化class
四、抽象類能夠包含成員變量、方法(普通方法、抽象方法均可以)、構造器,初始化塊,內部類(接口、枚舉)5種成分import
五、抽象類的構造器不能用於建立實例,只能用於被其子類調用
六、包含抽象方法的類,只能被定義爲抽象類
七、抽象類裏能夠沒有抽象方法
八、類包含抽象方法是指:
.8.一、直接定義了一個抽象方法
.8.二、繼承了一個抽象父類,但沒有徹底實現父類的抽象方法
.8.三、實現了一個接口,但沒有徹底實現接口包含的抽象方法
九、概括起來,抽象類能夠用 「有得有失」 四個字來形容:
有得:抽象類多了一個能力,能包含抽象方法
有失:抽象類失去了一個能力,不能用於建立實例
十、使用 abstract 修飾的類必須被繼承,使用 abstract 修飾的方法必須被重寫
使用 final 修飾的類不能被繼承,使用 final 修飾的方法不能被重寫
因此 abstract 和 final 永遠不能一塊兒用
以下代碼定義了一個抽象類,並被不一樣的子類繼承實現:
import static java.lang.System.*; //-定義一個抽象類,做爲父類 abstract class Shape{ { out.println("執行Shape類的普通初始化塊!"); } private String color; //-定義兩個抽象方法,讓子類去重寫實現 public abstract double getPerimeter(); public abstract String getType(); public Shape(){ } public Shape(String color){ out.println("執行帶參數的Shape類構造器!"); this.color=color; } public String getColor(){ return this.color; } public void setColor(String color){ this.color=color; } } //-子類 繼承抽象父類 class Triangle extends Shape{ private double a; private double b; private double c; public Triangle(String color,double a,double b,double c){ //-super關鍵字 調用父類構造器 super(color); setSides(a,b,c); } public void setSides(double a,double b,double c){ if(a>=b+c||b>=a+c||c>=a+b){ out.println("三角形的兩邊之和必須大於第三邊!"); return; } this.a=a; this.b=b; this.c=c; } //-重寫實現父類 getPerimeter() 方法 public double getPerimeter(){ return a+b+c; } //-重寫實現父類 getType() 方法 public String getType(){ return "三角形"; } } //-子類 繼承抽象父類 public class Circle extends Shape{ private double radius; public Circle(String color,double radius){ //-super關鍵字 調用父類構造器 super(color); this.radius=radius; } //-重寫實現父類 getPerimeter() 方法 public double getPerimeter(){ return 2*Math.PI*radius; } //-重寫實現父類 getType() 方法 public String getType(){ return "圓形"; } public void setRadius(double radius){ this.radius=radius; } public double getRadius(){ return this.radius; } public static void main(String[] args){ //-分別調用兩個子類中重寫的 方法: Shape s1=new Triangle("紅色",3,4,5); out.println("周長是:"+s1.getPerimeter()); out.println("圖形是:"+s1.getType()); out.println(); Shape s2=new Circle("藍色",5); out.println("周長是:"+s2.getPerimeter()); out.println("圖形是:"+s2.getType()); out.println(); //-改變一下寫法: Triangle s3=new Triangle("紅色",3,4,5); out.println("周長是:"+s3.getPerimeter()); out.println("圖形是:"+s3.getType()); out.println(); Circle s4=new Circle("藍色",5); out.println("周長是:"+s4.getPerimeter()); out.println("圖形是:"+s4.getType()); } }
運行結果:
如上代碼看到:利用抽象類和抽象方法,能夠更好的發揮多態的優點,使程序能夠更靈活,可是不用抽象類抽象方法,結果是同樣的。
注:
一、abstract 不能修飾成員變量,不能修飾局部變量,即:沒有抽象成員變量、抽象局部變量的說法
二、abstract 不能修飾構造器,也沒有抽象構造器的說法,抽象類裏定義的構造器只能是普通構造器
三、當使用 static 修飾方法時,表示這個方法屬於類自己,即經過類就能調用該方法,但若是該方法被定義爲抽象方法,當用該類來調用該方法時,就會出現錯誤,即調用了一個沒有方法體的方法,所以: static 和 abstract 不能同時修飾一個方法,即沒有所謂的類抽象方法
四、static 和 abstract 並非絕對互斥的,他們能夠同時修飾內部類
五、abstract 修飾的方法只有被子類重寫纔有意義,所以 abstract 方法不能定義爲 private 訪問權限,即:abstract 和 private 不能同時修飾方法