原创文章,转载请注明: 转载自工学1号馆
使用了关键词abstract声明的类叫作“抽象类”。如果一个类里包含了一个或多个抽象方法,类就必须指定abstract(抽象)。“抽象方法”,属于一种不完整的方法,只含有一个声明,没有方法主体。
抽象类
抽象类:代表一个抽象概念的类
- 没有具体实例对象的类,不能使用new方法进行实例化
- 类前需加修饰符abstract
- 可包含常规类能够包含的任何东西,例如构造方法,非抽象方法
- 也可包含抽象方法,这种方法只有方法的声明,而没有方法的实现
- 抽象类是类层次中较高层次的概括,抽象类的作用是让其他类来继承它的抽象化的特征
- 抽象类中可以包括被它的所有子类共享的公共行为
- 抽象类可以包括被它的所有子类共享的公共属性
- 在程序中不能用抽象类作为模板来创建对象;
- 在用户生成实例时强迫用户生成更具体的实例,保证代码的安全性
举个例子:
将所有图形的公共属性及方法抽象到抽象类Shape。再将2D及3D对象的特性分别抽取出来,形成两个抽象类TwoDimensionalShape及ThreeDimensionalShape
–2D图形包括Circles、Triangles、Rectangles和Squares
–3D图形包括Cube、Sphere、或Tetrahedron
–在UML中,抽象类的类名为斜体,以与具体类相区别:

抽象类声明的语法形式为
abstract class Number {
. . .
}
抽象方法
声明的语法形式为:
public abstract <returnType> <methodName>(…);
仅有方法头,而没有方法体和操作实现,具体实现由当前类的不同子类在它们各自的类声明中完成,抽象类可以包含抽象方法
需注意的问题:
- 一个抽象类的子类如果不是抽象类,则它必须为父类中的所有抽象方法书写方法体,即重写父类中的所有抽象方法
- 只有抽象类才能具有抽象方法,即如果一个类中含有抽象方法,则必须将这个类声明为抽象类
- 除了抽象方法,抽象类中还可以包括非抽象方法
抽象方法的优点:
- 隐藏具体的细节信息,所有的子类使用的都是相同的方法头,其中包含了调用该方法时需要了解的全部信息
- 强迫子类完成指定的行为,规定其子类需要用到的“标准”行为
举一个绘图的例子:

各种图形都需要实现绘图方法,可在它们的抽象父类中声明一个draw抽象方法
abstract class GraphicObject {
int x, y;
void moveTo(int newX, int newY) { . . . }
abstract void draw();
}
然后在每一个子类中重写draw方法,例如:
class Circle extends GraphicObject {
void draw() { . . . }
}
class Rectangle extends GraphicObject {
void draw() { . . . }
}
抽象类中还可以包括具体数据和具体方法
举一个例子,首先定义一个抽象类:
abstract class Person {
private String name; //具体数据
public Person(String n) { //构造函数
name = n;
}
public String getName() { //具体方法
return name;
}
public abstract String getDescription(); //抽象方法
}
下面通过抽象类Person扩展一个具体子类Student:
class Student extends Person {
private String major;
public Student(String n, String m) {
super(n);
major = m;
}
public String getDescription() { //实现抽象类中的getDescription方法
return "a student majoring in " + major;
}
}
通过抽象类Person扩展一个具体子类Employee:
class Employee extends Person {
private double salary;
private Date hireDay;
public Employee(String n, double s, int year, int month, int day) {
super(n);
salary = s;
GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
hireDay = calendar.getTime();
}
public double getSalary() {
return salary;
}
public Date getDate() {
return hireDay;
}
public String getDescription() { //实现抽象类中的getDescription方法
return String.format("an employee with a salary of $%.2f", salary);
}
public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
}
}
抽象类即使不含抽象方法,也可以声明为抽象类,抽象类不能实例化
可以定义一个抽象类的对象变量,但是它只能引用非抽象子类的对象:
Person p = new Student("wuyudong", "mather");
测试程序如下:
public class javatest {
public static void main(String[] args) {
Person[] people = new Person[2];
people[0] = new Employee("Hary Hacker", 50000, 1989, 10, 1);
people[1] = new Student("Maria Morris", "Computer science");
for(Person p : people)
System.out.println(p.getName() + ", " + p.getDescription());
}
}
运行结果如下:
Hary Hacker, an employee with a salary of $50000.00
Maria Morris, a student majoring in Computer science
再举一个例子:
先定义一个几何抽象类GeometricObject:
import java.util.*;
public abstract class GeometricObject {
private String color = "write";
private boolean filled;
private Date dateCreated;
//构造函数(protected类型)
protected GeometricObject() {
dateCreated = new Date();
}
protected GeometricObject(String color, boolean filled) {
dateCreated = new Date();
this.filled = filled;
this.color = color;
}
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 String toString() {
return "created on" + dateCreated + "\ncolor: " + color + " and filled: " + filled;
}
public abstract double getArea(); //抽象方法
public abstract double getPerimeter(); //抽象方法
}
定义一个具体类Circle继承抽象类:
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 getArea() { //实现抽象类中的抽象方法getArea()
return radius * radius * Math.PI;
}
public double getPerimeter() { //实现抽象类中的抽象方法getPerimeter()
return radius * 2 * Math.PI;
}
}
定义一个具体类Rectangle继承抽象类:
public class Rectangle extends GeometricObject {
private double width;
private double heigth;
public Rectangle() {
}
public Rectangle(double width, double heigth) {
this.width = width;
this.heigth = heigth;
}
public Rectangle(double width, double heigth, String color, boolean filled) {
this.width = width;
this.heigth = heigth;
setColor(color);
setFilled(filled);
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeigth() {
return heigth;
}
public void setHeigth(double heigth) {
this.heigth = heigth;
}
public double getArea() {
return width * heigth;
}
public double getPerimeter() {
return 2 * (width + heigth);
}
}

Comments