73.利用抽象类实现模板设计模式
有时候,我们会碰到另外的一种情况,比如,银行利息的计算,都是利率乘以本金和存款时间,但是,各种存款方式计算利率的方式的不同,一般而言,定期的存款利率比活期的利率要高;而定期的时间越长,它的利率也越高。因此,我们在设计“银行账户”这个类的时候,我们可以将计算利息这个方法定义成抽象方法,然后,再在各种不同类型账号的子类中来具体实现这个方法。但是,对于这个方法而言,有更好的一种设计思路:将这个方法中计算利息的算法骨架搭建出来,而对于一些细节,推迟到子类中来实现。这种设计的好处是,避免了子类设计中的随意性。
我们来看上面这个思路的实现方式。
abstract class LoanAccount {
// 利息
private double interest;
// 本金
private double fund;
public double calculateInterest() {
// 用于计算利息的算法:本金*利率,
// 但是利率的算法实现并没有在这个类中实现
interest = getFund() * getInterestRate();
System.out.println(interest);
return interest;
}
public void setFund(double fund) {
this.fund = fund;
}
public double getFund() {
return this.fund;
}
/**
* 不同的存款类型有不同的利率, 因此,不在这个父类中实现利率的计算方法, 而将它推迟到子类中实现
*/
protected abstract double getInterestRate();
}
对于刚才讨论的银行的账户的例子,我们可以给所有类型的账户定义一个超类LoanAccount,在这个超类中,有一个用于计算利息的方法caculateInterest(),已经将它的算法写好了,这个方法返回一个“本金*利率” 的值。但是,因为其中的利率根据存款类型的不同而不同,所以没有具体的实现获得利率的方法,所以,将这个获得利率的方法放到子类中去实现,根据不同的子类,设计出不同的获得利率的方法。
下面是继承了这个抽象类的一个子类:
class AccountA extends LoanAccount{
//只需要实现父类中没有实现的用于获取利率的抽象方法
public double getInterestRate(){
return 10.0;
}
}
在这个子类中,没有加上自己的属性,它只是简单的实现了父类中的抽象方法getInterestRate,这样,这个类就成了一个完整的账户类了。可以使用以下的方式来使用这个类:
public class TestAccount {
/**
* @param 本金
*
*/
public static void main(String args[]) {
AccountA account = new AccountA();
account.setFund(100.0);
account.calculateInterest();
}
}