工学1号馆

home

java核心系列8-抽象类

By Wu Yudong on June 11, 2015

原创文章,转载请注明: 转载自工学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

No comments yet.
To verify that you are human, please fill in "七"(required)