抽象类(abstract class)
抽象类(abstract class): 如果一个class定义了方法,但没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract修饰。
如果父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名,目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法:
class Person {
public abstract void run();
}
把一个方法声明为abstract,表示它是一个抽象方法,本身没有实现任何方法语句。因为这个抽象方法本身是无法执行的,所以,Person类也无法被实例化。编译器会告诉我们,无法编译Person类,因为它包含抽象方法。
必须把Person类本身也声明为abstract,才能正确编译它:
abstract class Person {
public abstract void run();
}
实例:
abstract class Person {
public abstract void run();
}
class Student extends Person {
@Override
public void run() { … }
}
class Teacher extends Person {
@Override
public void run() { … }
}
但抽象类无法被实例化, 在生成一个新对象的时候, 例如Person p = new Person();
的结果就是编译错误。这是因为抽象类本身被设计成只能用于被继承
。即, 当父类为抽象类时, 子类必须使用覆写@Override
。
对于面向抽象的变成, 在我们定义好左右的父类和子类时, 我们可以直接使用抽象类Person类型去引用子类的实例, 而不用关心具体子类型:
Person s = new Student();
Person t = new Teacher();
Person e = new Employee();
s.run();
t.run();
e.run();
实例:
用抽象类给一个有工资收入和稿费收入的小伙伴算税:
public class Main {
public static void main(String[] args) {
Income[] incomes = new Income[] { new SalaryIncome(7500), new RoyaltyIncome(12000) };
double total = 0;
for (Income income:incomes) {
total = total + income.getTax();
}
System.out.println(total);
}
}
/**
* 定义抽象类Income
*/
public abstract class Income {
protected double income;
public Income(double income) {
this.income=income;
}
public abstract double getTax();
}
public class SalaryIncome extends Income{
public SalaryIncome(double income) {
super(income);
}
@Override
public double getTax() {
if (income>5000) {
return (income-5000)*0.2;
}
else {
return 0;
}
}
}
/**
* 稿费收入税率是20%
*/
public class RoyaltyIncome extends Income{
public RoyaltyIncome(double income) {
super(income);
}
@Override
public double getTax() {
return income*0.2;
}
}
//结果为2900;