抽象类
当父类的一些方法无法给出具体实现时,可以用abstract关键字来修饰该方法,不写方法体,把方法变成抽象方法,同时这个类也必须被修改为抽象类
抽象类的语法
abstract class XX {//这是抽象类
private String name;
public XX(String name) {
this.name = name;
}
public abstract void YY(); //这是抽象方法
}
抽象类的使用细节
-
抽象类可以没有抽象方法
-
抽象类不能被实例化,但可以有构造器
-
一旦类包含了abstract方法,则这个类必须被声明为abstract
-
abstract只能修饰类和方法
-
抽象类的本质还是类,可以有类的一切内容
-
抽象方法不能有主体,即不能实现
-
如果一个类继承了抽象类,则它也必须实现抽象类的所有抽象方法,除非他自己也是抽象类
-
抽象方法不能被final、static、private修饰,因为这些都会阻碍类方法的重写
练习题
1)思考:abstract final class A{}能编译通过吗,why?
2)思考:abstract public static void test2()能编译通过吗,why?
3)思考:abstract private void test3();能编译通过吗,why?
答案是:都不能通过编译,final、static、private三者均阻碍类方法的重写
4)编写一个Employee类,声明为抽象类,包含如下三个属性:name,id,salary,提供必要的构造器和抽象方法:work()。对于Manager类来说,他既是员工,还具有奖金(bonus)的属性。请使用继承的思想,设计CommonEmployee类和Manager类,要求类中提供必要的方法进行属性访问,实现work(),提示“经理/普通员工名字工作中…
答案代码略:比较简单也比较长,就不放了
抽象类的最佳实践——模板设计模式
先阅读下面这段代码
public class TestTemplate {
public static void main(String[] args) {
new AA().job();
new BB().job();
}
}
class AA {
public void job() {
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 1; i <= 100000000; i++) {
sum += i;
}
long end = System.currentTimeMillis();
System.out.println("AA耗时:" + (end - start));
}
}
class BB {
public void job() {
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 1; i <= 10000000; i++) {
sum *= i;
}
long end = System.currentTimeMillis();
System.out.println("BB耗时:" + (end - start));
}
}
我们可以发现,两个类中的job方法其实有重复性逻辑,我们考虑让其变简洁
于是我们可以考虑把job方法中的计时逻辑提取出来,只在job方法中保留工作逻辑
public void calTime() {
long start = System.currentTimeMillis();
this.job();
long end = System.currentTimeMillis();
System.out.println("BB耗时:" + (end - start));
}
public void job() {
int sum = 0;
for (int i = 1; i <= 100000000; i++) {
sum += i;
}
}
这样虽然job里的内容少了,但是整体代码量并没有减轻,并且calTime方法的大部分逻辑在AA类和BB类中是重合的。假如还有CC、DD类,那会更加臃肿。
为了让代码更加简洁,复用性更高,我们对代码进行更进一步的修改,考虑把calTime方法统一提取到一个更高级别的类,在其中需要调用job方法,job方法的具体实现存在于子类中。
public class TestTemplate {
public static void main(String[] args) {
new AA().calTime();
new BB().calTime();
}
}
abstract class Template {
public void calTime() {
long start = System.currentTimeMillis();
this.job();
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
}
public abstract void job();
}
class AA extends Template {
public void job() {
int sum = 0;
for (int i = 1; i <= 100000000; i++) {
sum += i;
}
}
}
class BB extends Template {
public void job() {
int sum = 0;
for (int i = 1; i <= 100000000; i++) {
sum += i;
}
}
}
简单的说,抽象类的意义就是提升代码可复用性(把公共代码提取到父类抽象类中),同时定义统一规范(用抽象方法强制要求子类实现某些行为),告诉其他人,这个抽象类里哪些方法需要得到重写
2 个帖子 - 1 位参与者