Java中的抽象类

Java中的抽象类

引言

在java程序中,子类往往更加明确和具体,但是父类往往十分笼统。有的时候,一个父类设计的非常抽象,抽象到它都没有任何具体的实例,这种类就称为抽象类。

抽象类与抽象方法

在类的头部使用abstract修饰符表示该类为抽象类

(以下所有代码均来自最近在看的《Java语言程序设计与数据结构》)

package AboutAbstract;

import java.util.Date;

//该类为抽象类
public abstract class GeometricObject {
    private String color = "white";
    private  boolean filled;
    private java.util.Date dateCreated;

  //构造方法
    protected GeometricObject() {
        dateCreated = new java.util.Date();
    }

    protected GeometricObject(String color,boolean filled) {
        dateCreated = new java.util.Date();
        this.color = color;
        this.filled = filled;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public boolean isFilled() {
        return filled;
    }

    public void setFilled(boolean filled) {
        this.filled = filled;
    }

    public Date getDateCreated() {
        return dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }

    @Override
    public String toString() {
        return "created on" + dateCreated + "\ncolor:" + color +"and filled:" + filled;
    }
  
		//抽象方法
    public abstract double getArea();

    public abstract double getPerimeter();
}

可以看到,代码的最后两行就是定义在抽象类中的抽象方法,抽象方法不能在抽象类中具体实现。

使用抽象方法

我们已经知道,在抽象类中定义的抽象方法不能在抽象类中具体实现,我们要在子类中根据自身需求来实现父类的抽象方法

子类:圆形

package AboutAbstract;

import Hongbao.Mananger;

public class Circle extends GeometricObject{

    private double radius;
		//构造方法
    public Circle() {

    }
    public Circle(double radius) {
        this.radius = radius;
    }
    public Circle(double radius,String color,boolean filled) {
        this.radius = radius;
        setColor(color);
        setFilled(filled);
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

   
    public double getDiameter() {
        return 2 * radius;
    }

  	//子类中具体实现抽象方法
   	public double getArea() {
        return radius * radius * Math.PI;
    }
		//子类中具体实现抽象方法
    public double getPerimeter() {
        return 2 * radius * Math.PI;
    }

    public void printCircle() {
        System.out.println("The circle is created" + getDateCreated() + "and the radius is" + radius);
    }

}

子类:矩形

package AboutAbstract;

public class Rectangle extends GeometricObject{
    private double width;
    private double height;

    public Rectangle() {}

    public Rectangle(double width,double height) {
        this.width = width;
        this.height = height;
    }

    public Rectangle(double width,double height,String color,boolean filled) {
        this.width = width;
        this.height = height;
        setColor(color);
        setFilled(filled);
    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }
  
  	//子类中具体实现抽象方法
    public double getArea() {
        return width * height;
    }
		//子类中具体实现抽象方法
    public double getPerimeter() {
        return 2 * (width + height);
    }
}

测试:

package AboutAbstract;

public class TestGeometriObject {
    public static void main(String[] args) {
      	
      	//向下转型
        GeometricObject geoObject1 = new Circle(5);
        GeometricObject geoObject2 = new Rectangle(5,3);

        System.out.println("The two Objects have the same area?" + equalArea(geoObject1,geoObject2));

        displayGeometricObject(geoObject1);
        displayGeometricObject(geoObject2);
    }

    public static boolean equalArea(GeometricObject object1,GeometricObject object2) {
        return object1.getArea() == object2.getArea();
    }

    public static void displayGeometricObject(GeometricObject object) {
        System.out.println();
        System.out.println("The area is" + object.getArea());
        System.out.println("The perimeter is" + object.getPerimeter());
    }
}

为何要使用抽象方法

我们可以观察到,圆形和矩形的面积计算公式不同,当我们想要比较两者的面积时,我们可以使用抽象方法getArea,在圆形子类中具体实现为圆形的计算面积的公式,在矩形子类中具体实现为矩形的计算面积的公式。

抽象类的几点说明

  • 抽象方法不能包含在非抽象类中
  • 抽象类可以没有抽象方法(个人觉得抽象类里不放抽象方法,没有多大意义)这个抽象类用于作为定义新子类的基类
  • 如果抽象父类的子类不能实现其所有的抽象方法,则子类也必须定义为抽象的(非抽象子类中,必须实现所有抽象方法)
  • 抽象方法是非静态的
  • 抽象类不能通过new操作来初始化
  • 抽象类里面可以定义它的构造方法,这个构造方法在它的子类的构造方法中调用
  • 即使子类的父类是具体的,子类也可以是抽象的
  • 不能用new操作符从一个抽象类创建一个实例,但是抽象类可以作为一种数据类型,比如创建一个抽象类的数组

以上是关于抽象类的一些介绍,下面谈谈我个人对抽象类的理解,我认为抽象类就好比我们生活中所说的那里,比如说,“咱们今天去那里吃饭怎么样?”,”我上学那里好吃的可多了“,这个那里,就像一个抽象类一样,然后这个抽象类里都是含有相同的抽象方法的,比如”那里“的布局啊,风景啊等等,但是每个地方又各不相同,所以我们具体的”那里“就要来具体描述,这就对应着抽象方法需要子类去具体实现。当有两个人在描述自己想要向别人介绍的地方时,肯定都是从相同的角度出发来介绍,比如说A说我们那有许多树,有一座庙,B相应的也要介绍,我们那树不多,没有庙,这就对应着子类要实现所有的抽象方法。

当然以上只是一个类比,还是有不同之处的,抽象类的具体好处,还是得在实际工程中才能体会到。

posted @ 2020-04-30 08:37  阿-栋  阅读(395)  评论(0编辑  收藏  举报