java学习分享之抽象类

java学习分享之抽象类
java学习分享之抽象类

抽象类

当父类的一些方法无法给出具体实现时,可以用abstract关键字来修饰该方法,不写方法体,把方法变成抽象方法,同时这个类也必须被修改为抽象类

抽象类的语法

abstract class XX {//这是抽象类
    private String name;
​
    public XX(String name) {
        this.name = name;
    }
​
    public abstract void YY(); //这是抽象方法
}

抽象类的使用细节

  1. 抽象类可以没有抽象方法

  2. 抽象类不能被实例化,但可以有构造器

  3. 一旦类包含了abstract方法,则这个类必须被声明为abstract

  4. abstract只能修饰类和方法

  5. 抽象类的本质还是类,可以有类的一切内容

  6. 抽象方法不能有主体,即不能实现

  7. 如果一个类继承了抽象类,则它也必须实现抽象类的所有抽象方法,除非他自己也是抽象类

  8. 抽象方法不能被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 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文