从某种角度看,祖先类更加通用,人们只是把它作为其他类的基类,而不作为想使用的特定的实例类。这种情况下,我们可以在基类中定义抽象方法。
抽象方法充当占位的角色,它们的具体实现在子类中。
为了提高程序的清晰度,包括一个或多个抽象的类本身必须被声明为抽象的。
除了抽象方法之外,抽象类还可以包含具体数据和方法。
诶? 有点乱。上代码:
先来一个抽象超类 Person:
package abstractClasses;
public abstract class Person {
public abstract String getDescription();
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
看吧,上面三句加黑的话一点问题都没有。
再来两个具体的子类:
Employee:
package abstractClasses;
import java.time.*;
public class Employee extends Person{
private double salary;
private LocalDate hireDay;
public Employee(String name, double salary, int year, int month, int day) {
super(name);
this.salary = salary;
hireDay = LocalDate.of(year, month, day);
}
public double getSalary() {
return salary;
}
public LocalDate getHireDay() {
return hireDay;
}
public String getDescription() {
return String.format("an employee with a salary of $%.2f", salary);
}
public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
}
}
Student:
package abstractClasses;
public class Student extends Person {
private String major;
/**
* @param name the student's name
* @param major the student's major
*/
public Student(String name, String major) {
// pass n to superclass constructor
super(name);
this.major = major;
}
public String getDescription() {
return "a student majoring in" + major;
}
}
类即便不含抽象方法,也可以将类声明为抽象类。
抽象类不能被实例化。也就是说,如果将一个类声明为 abstract,就不能创建这个类的对象。
需要注意,可以定义一个抽象类的对象变量,但是只能引用非抽象子类的对象。
测试代码:
package abstractClasses;
/**
* This program demonstrates abstract class.
* @version 1.8 2018-2-6
* @author ShenXueYan
*/
public class PersonTest {
public static void main(String[] args) {
Person[] people = new Person[2];
//fill the people array with Student and Employee objects
people[0] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
people[1] = new Student("Maria Morris", "computer science");
//print out names and descriptions of all Person objects
for(Person p : people) {
System.out.println(p.getName() + ", " + p.getDescription());
}
}
}