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