Java抽象(abstract)類的詳解(語法規則,設計思想,程式碼例項)
首先用關鍵字abstract修飾的類成為abstract類,如:
abstract A{
...
}
用關鍵字abstract修飾的方法稱為abstract方法。
注意:對於abstract方法,只允許宣告,不允許實現,而且不能使用final和abstract同時修飾一個方法,例如:
abstract int min(int x,int y)
1.abstract類中可以有abstract方法,也可以有非abstract方法
2.abstract類不能使用new運算建立物件
重點:如果一個非抽象類是某個抽象類的子類,那麼它必須重寫父類abstract方法,給出方法體。這就是為什麼不允許使用final和abstract同時修飾一個方法的原因
另外,如果一個abstract類是abstract類的子類,它可以重寫父類的abstract方法,也可以繼承這個方法。
下面給出一個例子:
abstract class A
{
abstract int sum(int x,int y);
int sub(int x,int y)
{
return x-y;
}
}
class B extends A'
{
int sum (int x,int y)//子類必須重寫父類的sum方法,因為他用abstract修飾
{
return x+y;
}
}
public class C
{
public static void main (String args[])
{
B b=new B();
int sum=b.sum(30,20);//呼叫重寫的方法
int sub=b.sub(30,20);//呼叫繼承的方法
System.out.println("sum="+sum);//輸出結果sum=50
System.out.println("sum="+sum);//輸出結果sum=10
}
}
其實,以上只是abstract類的語法知識,很簡單,以下才是abstract類的精華
細心讀者已經發現,abstract類的子類,必須重寫abstract類的abstract方法,那麼說明,abstract只關心操作,但不關心這些操作具體如果實現。具體操作可以由它的子類去重寫。
public class circle{
double r
Circle(double r){
this.r=r
}
public double getArea(){
return(3.14*r*r);
}
}
下面要設計一個Pillar類用與計算柱體的體積
public class Pillar
{
Circle bottom;
double height;
Pillar(Circle bottom,double height)
{
this.bottom=bottom;
this.height=height;
}
public double getVolume()
{
return bottom.getArea()*height
}
}
大家可以發現,這樣設計沒有一點問題對吧,但是,我現在需要求一個以長方體為底的柱體面積怎麼辦?是不是遇到問題了,我們需要修改Pillar類,才能實現。所以這種設計侷限性很大,對於軟體開發,後期無法有效維護。
我們重新設計:
編寫一個抽象類Geometry,該類定義了一個抽象方法getArea(),如下:
public abstract class Geometry
{
public abstract double getArea();
}
設計Pillar類,我們可以,面向Geometry類編寫程式碼,即將Geometry類的物件做為自己的成員,該成員可以呼叫Geometry的子類重寫getArea()方法,這樣就可以將計算底層面積的任務指派給Geometry的子類了
package Shape;
import java.nio.channels.Pipe;
public class Pillar {
Geometry bottom;
double height;
Pillar(Geometry bottom,double height){
this.bottom=bottom;
this.height=height;
}
public double getVolume(){
return bottom.getArea()*height;
}
}
下面設計Circle類與Rectangle類,二者必須重寫Geometry類中的getArea()方法來計算各自的面積。
package Shape;
public class Circle extends Geometry {
double r;
Circle(double r){
this.r=r;
}
public double getArea(){
return(3.14*r*r);
}
}
package Shape;
public class Rectangle extends Geometry {
double a;
double b;
Rectangle(double a,double b){
this.a=a;
this.b=b;
}
public double getArea(){
return a*b;
}
}
下面寫下面的程式展示執行效果
package Shape;
public class Application {
public static void main(String args[]){
Pillar pillar;
Geometry bottom;
bottom = new Rectangle(12,22);
pillar = new Pillar(bottom,58);
System.out.println("矩形底的柱體的體積"+pillar.getVolume());
bottom = new Circle(10);
pillar = new Pillar(bottom,58);
System.out.println("圓形底的柱體的體積"+pillar.getVolume());
bottom = new Triangle(6,8,10);
pillar = new Pillar(bottom,58);
System.out.println("三角形底的柱體的體積"+pillar.getVolume());
}
}
程式結果如圖:
我們來再增加一個用Triangle類
package Shape;
public class Triangle extends Geometry{
double a;
double b;
double c;
Triangle(double a,double b,double c){
this.a=a;
this.b=b;
this.c=c;
}
public double getArea(){
double p;
p=(a+b+c)/2;
return Math.sqrt(p*(p-a)*(p-b)*(p-c));
}
}
大家發現了嗎?我們不用修改Pillar類就可以計算以三角形為底的柱體的面積了。可以看到,使用abstract類使我們的程式靈活性更高,後期可維護性更強。