面向对象设计中,类继承的主要作用是扩充已有类的功能,子类可以根据自己的需要选择是否要覆写父类中的方法,一个设计完善的父类是无法强制子类的覆写约定,为了解决这个设计问题,提出了抽象类的概念。抽象类与普通类相比唯一增加的就是抽象方法的定义,同时抽象类在使用时要求必须被子类所继承,并且子类必须覆写全部抽象方法。
提示:关于类继承的使用
普通类是指一个设计完善的类,这个类可以直接产生实例化对象并且调用类中的属性或方法;而抽象类最大的特点是必须有子类,并且无法直接进行对象实例化操作。在实际开发中,很少会去继承设计完善的类,大多都会考虑继承抽象类。
9.1.1抽象类基本定义
定义使用:abstract class。在一个抽象类中可以利用abstract关键字定义若干个抽象方法,抽象类子类就必须在继承抽象类时强制覆写全部抽象方法。
范例:定义抽象类
package com.lxh.ninechapter;
abstract public class nine187 { //定义抽象类
private String mess;
public String getMess() { //普通方法
return mess;
}
public void setMess(String mess) { //普通方法
this.mess = mess;
}
public abstract String getInfo(); //抽象方法
}
定义抽象方法时只需要定义方法名称而不需要定义方法体,抽象类的定义就是在普通类的基础上追加抽象方法的结构。
抽象类不是一个完整的类,对于抽象类的使用需要按照以下原则使用。
- 抽象类必须提供有子类,子类使用extends继承一个抽象类。
- 抽象类的子类(不是抽象类)一定要覆写抽象类中的全部抽象方法。
- 抽象类的对象实例化可以利用对象多态性通过子类向上转型的方式完成。
范例:使用抽象类
package com.lxh.ninechapter;
abstract public class nine187 { //定义抽象类
private String mess;
public String getMess() { //普通方法
return mess;
}
public void setMess(String mess) { //普通方法
this.mess = mess;
}
public abstract String getInfo(); //抽象方法
}
package com.lxh.ninechapter;
public class nine188 extends nine187 {
@Override
public String getInfo() {
return super.getMess()+"信息";
}
}
package com.lxh.ninechapter;
public class java188 {
public static void main(String[] args) {
nine187 me=new nine188(); //子类为父类实例化;多态性;向上转型
me.setMess("ll"); //调用父类继承方法
System.out.println(me.getInfo());//调用被覆写的方法
}
}
执行结果
ll信息
本程序利用extends关键字定义了关键字的子类,子类中覆写了父类抽象类的抽象方法,在主类中利用对象向上转型原则,通过子类实例化了抽象类对象。这样调用抽象方法时就是子类所覆写的方法体。
提示:抽象类最大的特点就是无法自己直接进行对象实例化操作,在实际操作中,抽象类的主要目的进行过度操作使用,当你要使用抽象类进行开发的时候,往往都是在你设计中需要解决类继承问题时所带来的代码重复处理。
9.1.2抽象类相关说明
注意事项
1、抽象类必须由子类继承,抽象方法必须被覆写,所以在定义时不允许使用final关键字定义抽象类或抽象方法。
范例:错误的抽象类定义
public abstract final class nine189 {
public final abstract String getInfo();
}
2、抽象类中可以定义成员属性与普通方法,为了可以为抽象类中的成员属性初始化,可以在抽象类中提供抽象方法。子类在继承抽象类时会默认调用父类的无参构造,如果抽象类没有提供无参构造方法,则子类必须通过super()的形式调用指定参数的构造方法。
范例:抽象类中定义构造方法
package com.lxh.ninechapter;
public abstract class nine189 {
private String mss;
public String getMss() {
return mss;
}
public void setMss(String mss) {
this.mss = mss;
}
public abstract String getInfo(); //抽象方法
//没有提供无参构造,所以在子类必须明确调用单参构造
public nine189(String mss) {
this.mss = mss;
}
}
package com.lxh.ninechapter;
public class nine189son extends nine189{
public nine189son(String mss) {
super(mss); //调用单参构造
}
@Override
public String getInfo() { //覆写抽象方法,定义方法体
return super.getMss()+"信息链接";
}
}
package com.lxh.ninechapter;
public class java189 {
public static void main(String[] args) {
nine189 mss=new nine189son("kk");
System.out.println(mss.getInfo());
}
}
执行结果
kk信息链接
3、抽象类中允许没有抽象方法,即便没有抽象方法,也无法直接使用关键字new直接实例化抽象类对象。
4、抽象类中可以提供static方法,并且该类方法不受到抽象类实例化对象的限制。
范例:在抽象类中定义static方法
package com.lxh.ninechapter;
public abstract class nine190 {
public abstract String getinfo();
public static nine190 getins() {
return new nine190son();
}
}
package com.lxh.ninechapter;
public class nine190son extends nine190 {
@Override
public String getinfo() {
return "信息链接";
}
}
public class java190 {
public static void main(String[] args) {
nine190 info=nine190.getins();
System.out.println(info.getinfo());
}
}
执行结果
信息链接
本程序在抽象类中定义static方法,此发方法的主要目的是返回抽象类实例,这样在主类中通过静态方法获取抽象类对象并且实现getInfo()方法调用。
9.1.3模板设计模式
类的作用主要是可以对一类事物的共性特征进行抽象,抽象类的设计比普通类的级别要高,既抽象类是在类级别的进一步抽象。例如:
- 机器人:能量+工作;
- 人类:吃饭+睡觉+工作;
- 狗类:吃饭+睡觉;
3类事物都有各自的描述范围,但是这三类事物也有公共的行为方法可以进行抽象,这时就可以利用抽象类的结构进行三类事物的行为控制。
范例:设计实现
package com.lxh.ninechapter;
public abstract class Action {
public static final int EAT=1;
public static final int SLEEP=5;
public static final int WORK=10;
public abstract void eat();
public abstract void sleep();
public abstract void work();
public void command(int code) {
switch(code) {
case EAT:{
this.eat();
break;
}
case SLEEP:{
this.sleep();
break;
}
case WORK:{
this.work();
break;
}
case EAT+SLEEP+WORK:{
this.eat();
this.sleep();
this.work();
break;
}
}
}
}
package com.lxh.ninechapter;
public class Person extends Action{
@Override
public void eat() {
System.out.println("人安静的坐着吃饭");
}
@Override
public void sleep() {
System.out.println("人晚上躺在床上睡");
}
@Override
public void work() {
System.out.println("人有想法的工作");
}
}
package com.lxh.ninechapter;
public class Robot extends Action {
@Override
public void eat() {
System.out.println("插上电源增加能量");
}
@Override
public void sleep() {
}
@Override
public void work() {
System.out.println("按照固定的思路工作");
}
}
package com.lxh.ninechapter;
public class Dog extends Action {
@Override
public void eat() {
System.out.println("趴下吃食槽里的剩饭");
}
@Override
public void sleep() {
System.out.println("趴在地上睡");
}
@Override
public void work() {
}
}
package com.lxh.ninechapter;
public class java192 {
public static void main(String[] args) {
Action robotAction=new Robot();
Action dogAction=new Dog();
Action personAction=new Person();
System.out.println("-----------机器人行为-----------");
robotAction.command(Action.EAT);
robotAction.command(Action.SLEEP);
robotAction.command(Action.WORK);
System.out.println("-----------狗的行为-----------");
dogAction.command(Action.EAT);
dogAction.command(Action.SLEEP);
dogAction.command(Action.WORK);
System.out.println("-----------人的行为-----------");
personAction.command(Action.EAT);
personAction.command(Action.SLEEP);
personAction.command(Action.WORK);
}
}
执行结果
-----------机器人行为-----------
插上电源增加能量
按照固定的思路工作
-----------狗的行为-----------
趴下吃食槽里的剩饭
趴在地上睡
-----------人的行为-----------
人安静的坐着吃饭
人晚上躺在床上睡
人有想法的工作
对于暂时不需要的功能,以空方法体的方式进行实现