Java基础之(十九)抽象类
来源:互联网 发布:手机屏保软件下载 编辑:程序博客网 时间:2024/06/10 01:06
说明
在自上而下的继承层次结构中,位于上层的类更具有通用性,甚至可能更加抽象。从某种角度看,祖先类更加通用,它只包含一些最基本的成员,人们只将它作为派生其他类的基类,而不会用来创建对象。甚至,你可以只给出方法的定义而不实现,由子类根据具体需求来具体实现。
这种只给出方法定义而不具体实现的方法被称为抽象方法,抽象方法是没有方法体的,在代码的表达上就是没有“{}”。包含一个或多个抽象方法的类也必须被声明为抽象类。
使用 abstract 修饰符来表示抽象方法和抽象类。
抽象方法
只有方法的定义,没有方法体的方法被称为抽象方法:
abstract void fun();
看一个简单的例子:
class Person{ String name; int age; Person(String name,int age){ this.name = name; this.age = age; } public void info(){ System.out.println("此人名为"+ name+", 年龄是 "+age); } abstract void eat();}
输出结果:编译报错
包含一个或多个抽象方法的类也必须被声明为抽象类。
抽象类
在Java语言中使用abstract class来定义抽象类。
抽象类的规则如下:
抽象类不能被实例化,即无法使用new关键字来生成对象;
如果一个类当中包含有抽象方法,那么这个类必须被声明为抽象类;
如果一个类中没有抽象函数,它也可以声明为抽象类;
抽象类可以包含Field、方法(普通方法和抽象方法均可)、构造器、初始化块、内部类、枚举类。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。
下面定义一个Person抽象类:
abstract class Person{ String name; int age; protected Person(){ System.out.println("Person的构造函数"); } protected Person(String name,int age){ this.name = name; this.age = age; } public void info(){ System.out.println("此人名为"+ name+", 年龄是 "+age); } abstract void eat();}
上面的Person类里包含了成员变量,普通方法,抽象方法和构造器,抽象类的构造器定义为protected,因为它主要只用于被其子类调用。
下面定义一个Chinese类,Chinese类被定义成普通类,因此必须实现Person类里的所有抽象方法,通过复写的方式。
class Chinese extends Person{ String address; Chinese(){ super(); System.out.println("Chinese的构造函数"); } Chinese(String name,int age,String address){ super(name,age); this.address = address; } void eat(){ System.out.println("吃饭"); } }
上面的Chinese类继承了Person抽象类,并实现了抽象类的抽象方法,是一个普通类,因此可以创建实例。
class Test{ public void mian(String[] args){ Person p = new Chinese(); p.eat(); }}
输出结果:Person的构造函数Chinese的构造函数吃饭
使用abstract的注意事项
利用抽象类和抽象方法的优势,我们可以更好的发挥多态的优势,使程序更加灵活。
abstract修饰的类只能被继承;abstract修饰的方法必须由子类复写实现。final修饰的类不能被继承,final修饰的方法不能被重写。因此,final和abstract不能同时使用。
abstract不能用于修饰Field、局部变量、构造器
abstract不能和static同时使用
abstract不能和private同时使用
抽象类的作用
当编写一个类时,往往会为该类定义一些方法,这些方法用于描述该类的行为方式,这些方法都有具体的方法体。但在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法确切地知道这些子类如何实现这些方法。例如我们定义了一个Printer(打印机)类,这个类提供了一个打印方法print();但不同的Printer子类打印的方式是不同的,(比如针式打印机和喷墨式打印机)Printer类无法准确地得知其子类的打印方式,这个时候就要用到抽象方法。
当然,可能有人会说,我们可以在Printer类中定义一个空方法,然后在子类中重写这个空方法。看下面这个例子:
class Printer{ void open(){ System.out.println("open"); } void close(){ System.out.println("close"); } void print(){ }}
class HPPrinter extends Printer{ void print(){ System.out.println("针式打印机"); }}
class CanonPrinter extends Printer{ void print(){ System.out.println("喷墨打印机"); }}
class Test{ public static void main(String[] args){ Printer p1 = new HPPrinter(); p1.open(); p1.close(); p1.print(); Printer p2 = new CanonPrinter(); p2.open(); p2.close(); p2.print(); }}
输出结果:open close针式打印机openclose喷墨打印机
虽然结果没有问题,但是代码中存在着安全隐患。
如果HPPrinter里忘记了重写print方法,这时代码却依然能够执行,p1.print();这行代码执行的时候,实际调用的是父类中的空方法,就不会出现想要的结果。
为了避免这种情况,Java建议使用abstract来修饰这种方法。
- Java基础之(十九)抽象类
- Java基础之(二十九)Java集合类
- java基础之----抽象类
- java基础之抽象类
- java基础之抽象类
- java基础之--抽象类
- JAVA菜鸟入门篇 - 抽象类、接口 (十九)
- 黑马程序员-----java基础十九(java之网络编程)
- Java基础之(二十一)接口与抽象类
- Java基础之抽象类与接口
- Java基础之继承,抽象类,接口
- Java语言基础之抽象类
- java基础之抽象类和接口
- java基础之抽象类和接口
- java基础之抽象类和接口
- java基础之抽象类和接口
- java基础之抽象类和接口
- Java基础之抽象类与接口
- POJ-2513-Colored Sticks
- BZOJ1683: [Usaco2005 Nov]City skyline 城市地平线 单调栈
- 物理术语的理解(二)
- [C/C++]在头文件中使用static定义变量意味着什么
- 大公司都有哪些开源项目
- Java基础之(十九)抽象类
- java基础知识(三)——java编程实例练习(附答案)
- Effective C++读书笔记---设计与声明
- MySQL笔记-常用数据库函数
- HDU-2041-超级楼梯
- 最近学习android MVP自己写了一个练手DEMO
- C#控制台基础 接口in抗变小实例
- 19种Android必杀技小工具
- PHP网络爬虫之CURL学习