首先用关键字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类使我们的程序灵活性更高,后期可维护性更强。