知识点

  • 什么是抽象类

    抽象类与普通类主要两点不同:

    1、在类的修饰符后面多了一个abstract关键字

    2、抽象类是不允许通过new来实例化的

    由于抽象类不能通过new来实例化,所以基本上是在继承中当做父类使用。

  • 什么是抽象方法

    抽象方法的定义需要加上abstract关键字,不能有方法体,以封号结尾,比如:

    public abstract void getOtherSalary();

    抽象方法的具体实现,需要在子类中实现。注意:static、final的方法,不能被申明为抽象方法。

  • 抽象类与抽象方法

    抽象类不一定包含抽象方法,但如果一个类包含了抽象方法,那这个类一定是抽象类,否则编译不通过。

  • 什么时候用抽象方法

    抽象方法通常用于父类中。父类通常都是用于定义一些公共方法、公共属性等,但是实际项目可能会出现某些方法定义在父类中,父类却无法给出具体的实现,此时就是抽象方法出场的时候了。比如下文实例中,职员在公司中的收入都包含基本工资以及绩效奖金,基本工资大家都一样,但是绩效奖金就因岗位而异了,所以绩效奖金在职员类中只是个方法体,没有具体实现。

  • 抽象方法与设计模式

    抽象方法在设计模式中有比较多的体现,特别是用于 模板方法设计模式,详见下文实例

实例

1.抽象方法的使用

需求描述:公司里的职员分为普通程序员和技术总监,所有职员的基本薪水都是10000元每个月,程序员的绩效奖金每个月3000元,技术总监的绩效奖金每个月20000元。

了解了需求后,我们先定义一个职员类Employee,如下:

  1. /**
  2. * 定义职工类,每个职工的薪水都由基本薪资跟绩效奖金组成
  3. */
  4. public abstract class Employee {
  5. /**
  6. * 岗位名称
  7. */
  8. private String jobName;
  9. /**
  10. * 所有职工的每月基本薪资都一样
  11. * @return
  12. */
  13. public int getBaseSalary(){
  14. return 10000;
  15. }
  16. /**
  17. * 所有职工都有绩效奖金,但是普通程序员跟技术总监的不一样,
  18. * 所以这里无法给出具体实现,需要在子类中实现
  19. * @return
  20. */
  21. public abstract int getOtherSalary();
  22. public String getJobName() {
  23. return jobName;
  24. }
  25. public void setJobName(String jobName) {
  26. this.jobName = jobName;
  27. }
  28. }

定义程序员类Coder,继承职员类,实现getOtherSalary() 方法,如下:

  1. /**
  2. * 程序员类,继承Employee类
  3. */
  4. public class Coder extends Employee{
  5. /**
  6. * 由于继承了Employee类,所以必须实现Employee类中的抽象方法getOtherSalary()
  7. * @return
  8. */
  9. @Override
  10. public int getOtherSalary() {
  11. return 3000;
  12. }
  13. }

定义技术总监类Cto,继承职员类,实现getOtherSalary() 方法,如下:

  1. /**
  2. * 技术总监类,继承Employee类
  3. */
  4. public class Cto extends Employee{
  5. /**
  6. * 由于继承了Employee类,所以必须实现Employee类中的抽象方法getOtherSalary()
  7. * @return
  8. */
  9. @Override
  10. public int getOtherSalary() {
  11. return 20000;
  12. }
  13. }

最后打印程序员与技术总监每个月的薪水:

  1. public class AbstractMain {
  2. public static void main(String[] args){
  3. Coder coder = new Coder();
  4. coder.setJobName("程序员");
  5. System.out.println(coder.getJobName() + "每个月薪资为:");
  6. System.out.println("基本薪资:" + coder.getBaseSalary() + "元");
  7. System.out.println("绩效奖金:" + coder.getOtherSalary() + "元");
  8. Cto cto = new Cto();
  9. cto.setJobName("技术总监");
  10. System.out.println(cto.getJobName() + "每个月薪资为:");
  11. System.out.println("基本薪资:" + cto.getBaseSalary() + "元");
  12. System.out.println("绩效奖金:" + cto.getOtherSalary() + "元");
  13. }
  14. }

执行以上程序后,输出:

  1. 程序员每个月薪资为:
  2. 基本薪资:10000
  3. 绩效奖金:3000
  4. 技术总监每个月薪资为:
  5. 基本薪资:10000
  6. 绩效奖金:20000

2.抽象方法与模板方法设计模式

在完成了以上需求后,此时又提出新需求,按照以下格式打印每个月的工资条,并且打印的顺序必须按以下格式打印出来:

  1. XXX每个月薪资为:
  2. 基本薪资:XXX
  3. 绩效奖金:XXX
  4. 该月总工资为:XXX

按照第一个例子的实现方式无法满足这个需求,第一个例子的打印顺序是由调用者决定的,无法统一控制。此时就是模板方法设计模式登场的时候了。基于第一个例子,改造一下职员类Employee,增加打印工资条的方法public final void printSalary()如下:

  1. /**
  2. * 定义职工类,每个职工的薪水都由基本薪资跟绩效奖金组成
  3. */
  4. public abstract class Employee {
  5. /**
  6. * 岗位名称
  7. */
  8. private String jobName;
  9. /**
  10. * 所有职工的每月基本薪资都一样
  11. * @return
  12. */
  13. public int getBaseSalary(){
  14. return 10000;
  15. }
  16. /**
  17. * 所有职工都有绩效奖金,但是普通程序员跟技术总监的不一样,
  18. * 所以这里无法给出具体实现,需要在子类中实现
  19. * @return
  20. */
  21. public abstract int getOtherSalary();
  22. /**
  23. * 获取每个月工资总额
  24. * @return
  25. */
  26. public int getTotalSalary(){
  27. return this.getBaseSalary() + this.getOtherSalary();
  28. }
  29. /**
  30. * 定义执行顺序模板,模板中有些方法(抽象方法)是要在子类中实现
  31. * 打印工资条,定义为final类,禁止被子类重写
  32. */
  33. public final void printSalary(){
  34. System.out.println(this.jobName + "每个月薪资为:");
  35. System.out.println("基本薪资:" + this.getBaseSalary() + "元");
  36. System.out.println("绩效奖金:" + this.getOtherSalary() + "元");
  37. System.out.println("该月总工资为:" + getTotalSalary() + "元");
  38. }
  39. public String getJobName() {
  40. return jobName;
  41. }
  42. public void setJobName(String jobName) {
  43. this.jobName = jobName;
  44. }
  45. }

打印每个月工资条:

  1. public class AbstractMain {
  2. public static void main(String[] args){
  3. Coder coder = new Coder();
  4. coder.setJobName("程序员");
  5. coder.printSalary();
  6. Cto cto = new Cto();
  7. cto.setJobName("技术总监");
  8. cto.printSalary();
  9. }
  10. }

以上执行结果为:

  1. 程序员每个月薪资为:
  2. 基本薪资:10000
  3. 绩效奖金:3000
  4. 该月总工资为:13000
  5. 技术总监每个月薪资为:
  6. 基本薪资:10000
  7. 绩效奖金:20000
  8. 该月总工资为:30000

源码获取

以上示例都可以通过我的GitHub获取完整的代码,点击获取

Java 抽象类 抽象方法 使用说明的更多相关文章

  1. Java 抽象类 抽象方法 接口

    #抽象类 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类除了不能实例化 ...

  2. Java基础 -- Java 抽象类 抽象方法

    总结: 1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过.只有抽象类的非抽象子类可以创建对象. 2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类. ...

  3. Java 学习(13):抽象类& 抽象方法& 封装

    目录 --- 抽象类 --- 封装 抽象类: 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的 ...

  4. Java抽象类中的抽象方法的参数对应的子类的方法的参数必须一致吗?

    同学你这个涉及了两个概念. 一个是抽象方法,一个是方法重载. 先说下概念: 抽象方法就是abstract描述的方法,它本身不含实现,必须由子类实现. 方法重载则是同一个方法名,但是参数类型或者参数个数 ...

  5. Java abstract关键字 抽象类 抽象方法

    用 abstract 修饰的类是抽象类,它不能生成对象 含有抽象方法的类称为抽象类 抽象方法使用 abstract 修饰 抽象类不能直接实例化,只能由子类实例化 举例 abstract class T ...

  6. java抽象类

    Java 抽象类 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类除了不 ...

  7. Java接口、Java抽象类、C++抽象类的区别

    由于这三种数据类型都是为了创建类层次结构的顶层构架,且用法有些许相似之处,这里简单区分一下: 接口: 接口用interface关键字定义, 名字一般使用-able形式的形容词. 接口通常定义抽象方法和 ...

  8. Java 抽象类与接口总结

    一.为什么要使用抽象类?有什么好处? 抽象类是通用接口.不同的子类可以用不同的方法表示此接口.通用接口建立起一种基本形式,以此表示所有子类的共同部分. 必须覆写父类abstract抽象的方法  含有抽 ...

  9. JAVA抽象类和接口的深入探讨

    Java 语言中,抽象类(abstract class) 和接口(interface) 是抽象思想的两种体现形式.初学者很容易把这两者搞混,所以Java面试中考抽象类和接口的区别的面试题也常有出现的. ...

随机推荐

  1. Redis实现高并发分布式锁

    分布式锁场景在分布式环境下多个操作需要以原子的方式执行首先启一个springboot项目,再引入redis依赖包: <!-- https://mvnrepository.com/artifa . ...

  2. deeplearning.ai 神经网络和深度学习 week2 神经网络基础

    1. Logistic回归是用于二分分类的算法. 对于m个样本的训练集,我们可能会习惯于使用for循环一个个处理,但在机器学习中,是把每一个样本写成一个列向量x,然后把m个列向量拼成一个矩阵X.这个矩 ...

  3. [LC] 142. Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. To r ...

  4. t分布|F分布|点估计与区间估计联系|

    应用统计学 推断统计需要样本形容总体,就要有统计量.注意必须总体是正态分布,否则统计量的分布不能得到.卡方分布和t分布只要样本大于30都近似于正态分布. t分布和F分布推导及应用(图): 总体比例是π ...

  5. nevertheless|magnificent |prosperous|

    ADV 然而;不过You use nevertheless when saying something that contrasts with what has just been said. Mos ...

  6. Java POI导出Excel不弹框选择下载路径(下载文件不选择下载路径,默认) Chrome

    在Chrome浏览器中,Java导出Excel文件时,浏览器弹出提示框,需要选择下载路径 在Chrome中的高级设置中,把“下载前询问每个文件的保存位置”去掉就解决了 DEEPLOVE(LC)

  7. Beautiful Soup的用法(五):select的使用

    原文地址:http://www.bugingcode.com/blog/beautiful_soup_select.html select 的功能跟find和find_all 一样用来选取特定的标签, ...

  8. wabpack踩坑

    webpack 打包时会用 NODE_ENV 来标识是生产环境还是开发环境光, "build": "NODE_ENV=production webpack", ...

  9. python 爬虫保存文件的几种方法

    import os os.makedirs('./img/', exist_ok=True) IMAGE_URL = "https://morvanzhou.github.io/static ...

  10. sql问题处理

    批量杀死MySQL连接 select concat('KILL ',id,';') from information_schema.processlist where Info like 'selec ...