1. 程式人生 > 其它 >Java抽象(abstract)類的詳解(語法規則,設計思想,程式碼例項)

Java抽象(abstract)類的詳解(語法規則,設計思想,程式碼例項)

技術標籤:Javajava程式語言抽象類設計模式程式人生

首先用關鍵字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類使我們的程式靈活性更高,後期可維護性更強