首先用关键字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());
    }
}

程序结果如图:

java中abstract的例子 abstract在java中的用法_抽象类


我们来再增加一个用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类就可以计算以三角形为底的柱体的面积了。

java中abstract的例子 abstract在java中的用法_java中abstract的例子_02

可以看到,使用abstract类使我们的程序灵活性更高,后期可维护性更强