Java abstract关键字的用法(附带实例)
在面向对象程序设计中,常常会遇到这样的问题,对于父类中的某些方法,其不同子类中的这些方法肯定有所不同,这些方法必须在子类中重写,故而根本无须在父类中实现这些方法。
面对这类问题,Java 提供了抽象类,对一系列看上去不同但本质上相同的具体概念进行抽象,用来表征对问题领域进行分析、设计中得出的抽象概念,使类设计的体系结构更加清晰。
Java 语言中提供了 abstract 关键字,表示抽象的意思。
用 abstract 关键字修饰的类称为抽象类,抽象类有类似“模板”的作用,我们可以定义抽象类来表征某些子类或对象的广义属类的共有特征,但是抽象类不能直接使用 new 关键字创建对象,只能被继承,并在其子类中将其特征具体化。
用 abstract 关键字修饰的方法称为抽象方法,它是一个不完整的方法,只有声明,没有方法体。抽象类可以包含抽象方法,也可以不包含。
定义抽象类和抽象方法的具体语法如下:
定义抽象类或抽象方法时,需要注意以下几点:
接下来,我们通过具体问题来体会抽象类与抽象方法的具体应用。几何形状是大家熟悉不过的,它们形状千姿百态,有圆形、正方形、三角形等,这些几何形状都可以计算面积,但是计算方法却不同。可见,计算面积是几何形状的共有特征,而不同的几何形状又有不同的具体实现。
于是,为了设计出结构清晰的几何形状面积计算类体系,我们可以先定义抽象的几何形状类 Shape 类,该类包含公共的颜色属性 color,也包含公共的面积计算方法 getArea(),显然该方法也必须是抽象的。接着,我们进一步定义圆形类 Circle 类和正方形类 Square 类,让这两个类继承 Shape 类,并实现 getArea() 方法。
接下来,我们给出上述问题的具体实现:
注意,抽象类不可以直接用 new 关键字创建对象,但并不能说明抽象类不可以创建对象。例如,程序中的 main() 方法中第 39 行代码就创建了抽象类 Shape 类的对象,但指向的是其子类的对象。
面对这类问题,Java 提供了抽象类,对一系列看上去不同但本质上相同的具体概念进行抽象,用来表征对问题领域进行分析、设计中得出的抽象概念,使类设计的体系结构更加清晰。
Java 语言中提供了 abstract 关键字,表示抽象的意思。
用 abstract 关键字修饰的类称为抽象类,抽象类有类似“模板”的作用,我们可以定义抽象类来表征某些子类或对象的广义属类的共有特征,但是抽象类不能直接使用 new 关键字创建对象,只能被继承,并在其子类中将其特征具体化。
用 abstract 关键字修饰的方法称为抽象方法,它是一个不完整的方法,只有声明,没有方法体。抽象类可以包含抽象方法,也可以不包含。
定义抽象类和抽象方法的具体语法如下:
abstract class 抽象类名 { // 定义抽象类,用abstract修饰 [访问修饰符]abstract 返回类型 方法名称(参数); // 定义抽象方法,用abstract修饰,无方法体 }通过 abstract 关键字标记,抽象类和抽象方法可以让开发人员明确该类或方法的作用,进而在继承抽象类时重写其抽象方法,以针对性地解决具体问题。
定义抽象类或抽象方法时,需要注意以下几点:
- 抽象类和抽象方法必须使用 abstract 修饰符来修饰,不能使用 private 修饰符,因为子类需要有继承抽象类的权限;
- 由于抽象类是需要被继承的,所以抽象类不能用 final 修饰,即关键字 abstract 和 final 不能同时使用;
- 抽象类不能被实例化,可以有构造方法和普通方法,且构造方法不能声明为抽象的;
- 普通方法内有方法体,而抽象方法不能有方法体;
- 抽象方法不能使用 static 修饰符来修饰,因为 static 修饰的方法可以通过类名调用,而调用一个没有方法体的方法会报错;
- 如果一个类继承了抽象类,则该类必须实现抽象类中的全部抽象方法,除非子类也是抽象类。
接下来,我们通过具体问题来体会抽象类与抽象方法的具体应用。几何形状是大家熟悉不过的,它们形状千姿百态,有圆形、正方形、三角形等,这些几何形状都可以计算面积,但是计算方法却不同。可见,计算面积是几何形状的共有特征,而不同的几何形状又有不同的具体实现。
于是,为了设计出结构清晰的几何形状面积计算类体系,我们可以先定义抽象的几何形状类 Shape 类,该类包含公共的颜色属性 color,也包含公共的面积计算方法 getArea(),显然该方法也必须是抽象的。接着,我们进一步定义圆形类 Circle 类和正方形类 Square 类,让这两个类继承 Shape 类,并实现 getArea() 方法。
接下来,我们给出上述问题的具体实现:
abstract class Shape { // 定义抽象的几何形状类Shape类 String color; public Shape(String color) { this.color = color; System.out.println("当前图形颜色是:" + color); } abstract double getArea(); // 求面积的抽象方法 } class Circle extends Shape { // 定义Shape类的子类Circle类 private final double PI = 3.1415926; // 声明圆周率常量 private double r; // 声明圆半径变量 public Circle(String color, double radius) { super(color); this.r = radius; } @Override double getArea() { // 重写抽象类中的getArea()方法 return PI * r * r; } } class Square extends Shape { // 定义Shape类的子类Square类 private double e; // 声明正方形的边长 public Square(String color, double edge) { super(color); this.e = edge; } @Override double getArea() { // 重写抽象类中的getArea()方法 return e * e; } } public class Demo { public static void main(String[] args) { Circle circle = new Circle("红色",3); System.out.println("圆的面积是:" + circle.getArea()); Shape square = new Square("绿色",4); System.out.println("正方形的面积是:" + square.getArea()); } }程序的运行结果如下:
当前图形颜色是:红色
圆的面积是:28.274333400000003
当前图形颜色是:绿色
正方形的面积是:16.0
注意,抽象类不可以直接用 new 关键字创建对象,但并不能说明抽象类不可以创建对象。例如,程序中的 main() 方法中第 39 行代码就创建了抽象类 Shape 类的对象,但指向的是其子类的对象。