Java面向对象软件开发
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.1.1 抽象类

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类,既然没有足够的信息描述一个具体的对象,因此这是一种不能实例化的类。抽象类往往用来描述我们在对具体问题进行分析、设计中得出的抽象概念。比如,如果进行一个图形编辑软件的开发,在进行具体问题分析时,存在着圆、三角形这样一些具体概念,它们是不同的,但是它们又都属于“形状”这样一个概念,即分类的标准就是具有形状,但形状是一个非常抽象概念,它并不能生成特定的对象,这个“形状类”就是一个抽象类。那么在Java语言中如何定义一个抽象类呢?

在Java语言中,用abstract关键字来修饰一个类时,这个类就是抽象类。一个抽象类只规定了其子类具有某种功能,并不规定子类中该功能是如何实现的,该功能的具体行为由子类负责实现。抽象类的抽象性是靠其中存在的抽象方法来体现的。当用abstract关键字来修饰一个方法时,该方法就是抽象方法。一个抽象方法只是声明一个方法,没有方法体(没有方法的具体实现),抽象方法的声明以分号结束。

定义一个抽象类的格式如下:

      abstract class AbstractClassName{
      …
      }

例如:

            public abstract class Shape{
                    public abstract double area();//抽象方法
                    public abstract double volume();//抽象方法
            }

上面的代码完成了对Shape抽象类的定义,可见定义抽象类和普通类差别不大,只是必须用abstract来修饰类名。它可以拥有一个或多个抽象方法,也可以没有定义抽象方法,但只要类中有一个方法被声明为抽象方法,则该类必须为抽象类。

当一个类被定义成abstract类时,表示一个抽象的概念,它不能用new关键字实例化对象,例如,上面定义的Shape类就是一个抽象类,只有被继承并在子类中重写其抽象方法,它才有意义。除抽象方法外,抽象类可以拥有和普通类一样的类成员。

特别提示:

不能用abstract修饰类的构造方法、静态方法和私有(private)方法。

例3-1】 定义一个代表形状的抽象类,并派生出圆柱体类和长方体类,计算底面半径为“2”,高为“3”的圆柱体体积和长、宽、高分别为“3”,“2”,“4”的长方体体积。

            //定义一个形状抽象类
            abstract class Shape{
                double radius,length,width,height;
                abstract double vol();            //求体积的抽象方法
                Shape(double r,double h){          //对半径和高进行初始化的构造方法
                    radius = r;
                    height = h;
                }
                Shape(double l,double w,double h){   //对长宽高进行初始化的构造方法
                    length = l;
                    width = w;
                    height = h;
                }
            }
             /**
             * 圆柱体类
             */
            class Circle extends Shape{
                Circle(double r,double h){
                    super(r,h);
                }
                double vol(){                  //重写父类抽象方法
                    return (3.1416*radius*radius*height);
                }
            }
             /**
             * 长方体类
             */
            class Rectangle extends Shape{
                Rectangle(double l,double w,double h){
                    super(l,w,h);
                }
                double vol(){                  //重写父类抽象方法
                    return (length*width*height);
                }
            }
            /**
            * 体类
            */
            public class AbstractClassDemo{
               public static void main(String[] args) {
                    Circle c = new Circle(2,3);
                    Rectangle r = new Rectangle(3,2,4);
                    System.out.println("圆柱体体积 ="+c.vol());
                    System.out.println("长方体体积 ="+r.vol());
                }
            }

程序的运行结果如下:

            圆柱体体积=37.6992
            长方体体积=24.0

在【例3-1】中,定义了一个Shape抽象类,通过对各种具体的形状(如长方体和圆柱体等)分析,发现它们都可以求体积,而它们都是形状中的一种,从而将求体积的方法定义在形状类中,而不具体实现它。该抽象类实际上提供了一个规范,每一个继承它的子类都必须要遵守这个规范,而如何去完成这个规范是子类自己的事情。

【思考】abstract修饰的类一定有abstract修饰的方法吗?