原文地址:http://www.work100.net/training/java-abstract.html

更多教程:光束云 - 免费课程

抽象类

序号 文内章节 视频
1 概述 -
2 Java抽象类 -
3 继承抽象类 -
4 抽象方法 -
5 总结 -

请参照如上章节导航进行阅读

1.概述

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

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

2.Java抽象类

在Java语言中使用 abstract class 来定义抽象类。如下实例:

  1. /* 文件名 : Employee.java */
  2. public abstract class Employee
  3. {
  4. private String name;
  5. private String address;
  6. private int number;
  7. public Employee(String name, String address, int number)
  8. {
  9. System.out.println("Constructing an Employee");
  10. this.name = name;
  11. this.address = address;
  12. this.number = number;
  13. }
  14. public double computePay()
  15. {
  16. System.out.println("Inside Employee computePay");
  17. return 0.0;
  18. }
  19. public void mailCheck()
  20. {
  21. System.out.println("Mailing a check to " + this.name
  22. + " " + this.address);
  23. }
  24. public String toString()
  25. {
  26. return name + " " + address + " " + number;
  27. }
  28. public String getName()
  29. {
  30. return name;
  31. }
  32. public String getAddress()
  33. {
  34. return address;
  35. }
  36. public void setAddress(String newAddress)
  37. {
  38. address = newAddress;
  39. }
  40. public int getNumber()
  41. {
  42. return number;
  43. }
  44. }

注意到该 Employee 类没有什么不同,尽管该类是抽象类,但是它仍然有 3 个成员变量,7 个成员方法和 1 个构造方法。 现在如果你尝试如下的例子:

  1. /* 文件名 : AbstractDemo.java */
  2. public class AbstractDemo
  3. {
  4. public static void main(String [] args)
  5. {
  6. /* 以下是不允许的,会引发错误 */
  7. Employee e = new Employee("George W.", "Houston, TX", 43);
  8. System.out.println("\n Call mailCheck using Employee reference--");
  9. e.mailCheck();
  10. }
  11. }

当你尝试编译 AbstractDemo 类时,会产生如下错误:

  1. Employee.java:46: Employee is abstract; cannot be instantiated
  2. Employee e = new Employee("George W.", "Houston, TX", 43);
  3. ^
  4. 1 error

3.继承抽象类

我们能通过一般的方法继承 Employee 类:

  1. /* 文件名 : Salary.java */
  2. public class Salary extends Employee
  3. {
  4. private double salary; //Annual salary
  5. public Salary(String name, String address, int number, double
  6. salary)
  7. {
  8. super(name, address, number);
  9. setSalary(salary);
  10. }
  11. public void mailCheck()
  12. {
  13. System.out.println("Within mailCheck of Salary class ");
  14. System.out.println("Mailing check to " + getName()
  15. + " with salary " + salary);
  16. }
  17. public double getSalary()
  18. {
  19. return salary;
  20. }
  21. public void setSalary(double newSalary)
  22. {
  23. if(newSalary >= 0.0)
  24. {
  25. salary = newSalary;
  26. }
  27. }
  28. public double computePay()
  29. {
  30. System.out.println("Computing salary pay for " + getName());
  31. return salary/52;
  32. }
  33. }

尽管我们不能实例化一个 Employee 类的对象,但是如果我们实例化一个 Salary 类对象,该对象将从 Employee 类继承 7 个成员方法,且通过该方法可以设置或获取三个成员变量。

  1. /* 文件名 : AbstractDemo.java */
  2. public class AbstractDemo
  3. {
  4. public static void main(String [] args)
  5. {
  6. Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
  7. Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
  8. System.out.println("Call mailCheck using Salary reference --");
  9. s.mailCheck();
  10. System.out.println("\n Call mailCheck using Employee reference--");
  11. e.mailCheck();
  12. }
  13. }

以上程序编译运行结果如下:

  1. Constructing an Employee
  2. Constructing an Employee
  3. Call mailCheck using Salary reference --
  4. Within mailCheck of Salary class
  5. Mailing check to Mohd Mohtashim with salary 3600.0
  6. Call mailCheck using Employee reference--
  7. Within mailCheck of Salary class
  8. Mailing check to John Adams with salary 2400.

4.抽象方法

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

  1. public abstract class Employee
  2. {
  3. private String name;
  4. private String address;
  5. private int number;
  6. public abstract double computePay();
  7. //其余代码
  8. }

声明抽象方法会造成以下两个结果:

  • 如果一个类包含抽象方法,那么该类必须是抽象类
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类

继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

如果 Salary 类继承了 Employee 类,那么它必须实现 computePay() 方法:

  1. /* 文件名 : Salary.java */
  2. public class Salary extends Employee
  3. {
  4. private double salary; // Annual salary
  5. public double computePay()
  6. {
  7. System.out.println("Computing salary pay for " + getName());
  8. return salary/52;
  9. }
  10. //其余代码
  11. }

5.总结

  • 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
  • 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  • 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
  • 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
  • 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

上一篇:多态

下一篇:封装


如果对课程内容感兴趣,可以扫码关注我们的 公众号QQ群,及时关注我们的课程更新


Java入门 - 面向对象 - 04.抽象类的更多相关文章

  1. JAVA入门 面向对象

    主要内容 1.类和对象的概念 2.什么是面向对象 3.什么对象的属性方法 4.何谓对象引用 5.实例化 类和对象的概念 万物皆对象,客观存在的事物皆为对象.我们大到名胜古迹,小道生活中的一件物品,例如 ...

  2. Java 基础 面向对象和抽象类

    面向对象变量 局部变量和成员变量区别 区别一:定义的位置不同 定义在类中的变量是成员变量 定义在方法中或者{}语句里面的变量是局部变量 区别二:在内存中的位置不同 成员变量存储在对内存的对象中 局部变 ...

  3. Java入门 - 面向对象 - 05.封装

    原文地址:http://www.work100.net/training/java-encapsulation.html 更多教程:光束云 - 免费课程 封装 序号 文内章节 视频 1 概述 2 封装 ...

  4. Java入门教程十(抽象类接口内部类匿名类)

    抽象类(abstract) 一个类只定义了一个为所有子类共享的一般形式,至于细节则交给每一个子类去实现,这种类没有任何具体的实例,只具有一些抽象的概念,那么这样的类称为抽象类. 在面向对象领域,抽象类 ...

  5. 十、Java基础---------面向对象之抽象类与接口

    抽象类(abstract)     当编写一个类时,时常会为该类定义一些方法,这些方法的使用用以描述该类的行为方式,那么这些方法都有具体的方法体.但是在某些情况下,某个父类只是知道子类应该包含怎样的方 ...

  6. java学习面向对象之抽象类

    什么是抽象类,之所以说抽象就是具体的反义词喽~抽象离我们最近的距离也就是初中的时候学过的美术课,抽象画派.拿一桶画彩就这么往画布上一泼,那就是抽象.那么java世界当中什么是抽象呢?我们再拿动物还有狗 ...

  7. Java:【面向对象:抽象类,接口】

    本文内容: 抽象类 接口 抽象类与接口的异同 首发日期:2018-03-24 抽象类: 虽然已经有了父类,但有时候父类也是无法直接描述某些共有属性的,比如哺乳类和人类都会叫,而一般来说哺乳类这个父类并 ...

  8. Java入门 面向对象第一天

    面向对象 人为抽象的一种编程模型,在理解面向对象的代码时要按照抽象的模型来理解,不能只从代码字面来理解复杂的问题,学会拆分成一个一个独立的小问题,通过解决每一个小问题,最后解决一个大问题 类 类是事物 ...

  9. Java入门 - 面向对象 - 01.继承

    原文地址:http://www.work100.net/training/java-inheritance.html 更多教程:光束云 - 免费课程 继承 序号 文内章节 视频 1 概述 2 继承的特 ...

随机推荐

  1. 2019-4-29-C#-从-short-转-byte-方法

    title author date CreateTime categories C# 从 short 转 byte 方法 lindexi 2019-4-29 12:8:39 +0800 2019-01 ...

  2. <Standard Template Library>标准模板库专项复习总结(二)

    4.队列 先进先出(FIFO)表 头文件:#include<queue> 变量的定义:queue<TYPE>queueName 成员函数: bool empty() 空队列返回 ...

  3. Android应用框架中的四个核心要点

    Android应用框架中的四个核心要点:活动(Activity).消息(Intent).视图(View).任务(Task) (一)活动Activity Android系统内部有专门的Activity堆 ...

  4. 使用Git和Github来管理自己的代码和笔记

    一.Github注册 1.先注册github.com的账号,官方网站: https://github.com/ 2.登录 3.创建仓库,仓库分公开的和私有的,公开的是免费的,私有的是收费的.我现在创建 ...

  5. 【时区问题】SpringBoot+mybatis查询mysql的datetime类型数据时间差14小时

    [时区问题]MyBatis查询MySQL的datetime类型数据时间差14小时 故障解决方式 与数据库连接时,定义时区,避免mybatis框架从mysql获取时区.在连接上加上 serverTime ...

  6. oracle数据库创建实例

    数据库已经安装完成,可以正常登陆查看用户等操作 system用户只能用normal身份登陆em.除非你对它授予了sysdba的系统权限或者syspoer系统权限. sys用户具有“SYSDBA”或者“ ...

  7. linux-iptables匹配条件总结(一)

    指定单个ip,示例如下: iptables -A INPUT -s 192.168.2.85 -j ACCEPT ![](https://img2018.cnblogs.com/blog/189009 ...

  8. Git是什么?

    Git是什么? Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控 ...

  9. $ [Contest \#4]$求和 思博题

    正解: 解题报告: 传送门$QwQ$ 一道看起来是数位$dp$其实并不是的题$QwQ$ 首先求$\sum_{l}^r$就变成$\sum_1^r-\sum_1^{l-1}$不说$QwQ$.现在就只要求$ ...

  10. Ecshop在模板中判断用户是否登陆,获取用户等级信息

    ecshop模板中smarty怎样判断用户等级.用户id.用户昵称用户名,请看以下方法,使用全局变量 <!-- {if $smarty.session.user_rank gt 1}--> ...