在面向对象中,所有的对象都是通过类来描述的。
但是并不是所有的类都用来描绘对象。
当一个类的属性不足以描绘一个对象的时候,这个类就是抽象类。
由于抽象类不包含实例对象,因此抽象类必须被继承。在Java中,抽象类表示的是一种继承的关系。一个类只能继承一个抽象类,而一个类却可以实现多个接口。
考虑这个应用场景,Employee和Student里面都继承自Person类,而Person类定义了一些基本的方法,例如获取名字之类的。但是Person超类肯定有很多方法没有定义全,在实际的使用中,也不会只生成Person对象,因此可以将Person定义为抽象类
- 为了提高程序的清晰度,包含一个或者多个抽象方法的类本身需要被声明为抽象的。
- 除了抽象方法外,抽象类还可以包含具体数据和具体方法。
public abstract class Person {
public abstract String getDescription();
private String name;
public Person(String name){
this.name = name;
}
public String getName(){
return name;
}
}
由于Persion类还不能足够生成一个人的Description,因此作为抽象方法,而Person类就定义为抽象类。Person抽象类除了抽象方法外,还可以包含自己的数据和方法,例如private String name;域
这个时候,当我定义一个员工类的时候,如果不实现抽象类的抽象方法,就会报错:
定义员工类:
package abstractClass;
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);
}
}
从这个图片可以看到,这个符号表示对抽象超类的抽象方法的实现,如果不是抽象类并且不实现抽象超类的抽象方法,那么就会报错。
定义学生类
package abstractClass;
public class Student extends Person{
private String major;
public Student(String name, String major){
super(name);
this.major = major;
}
public String getDescription(){
return "a student major in" + major;
}
}
类测试:
package abstractClass;
public class PersonTest {
public static void main(String[] args){
Person[] people = new Person[2];
people[0] = new Employee("Harry", 50000, 1989, 10, 1);
people[1] = new Student("Maria", "computer science");
for(Person p : people){
System.out.println(p.getName() + "," + p.getDescription());
}
}
}
测试结果
是否可以省略Person超类的抽象方法,而仅在Employee或者Student子类中定义getDescription呢。
如果这样的话,就不能通过p调用getDescription了,编译器只允许调用类中声明的方法。
在Java程序设计语言中,抽象方法是一个重要的概念。