在开发之中,一个类绝对不要去继承一个已经实现好的类,只能够继承抽象类或接口。
抽象类
在之前所学的类都属于普通类,普通类的特征是:类的结构很完整,并且可以直接产生实例化对象并使用。但是在普通类之中定义的方法都是具备方法体的“{}”,但是如果说现在一个类之中的某些方法希望强制子类覆写,则可以将其定义为抽象方法,抽象方法可以使用abstract关键字声明,而且声明时没有方法体,而包含抽象方法的类就成为抽象类,抽象类也要使用关键字abstract进行声明。
但是抽象类定义完成之后并不能像普通类那样直接使用关键字new进行对象实例化操纵(但是可以声明抽象类对象)。因为一旦一个类的实例化对象产生了,那么就意味着可以通过此对象调用类中方法,可是抽象方法没有方法体,所以一定无法进行调用,那么对于抽象类的使用原则如下:
- 抽象类一定要被在子类继承
- 抽象类的子类(如果不是抽象类)则必须覆写抽象类全部的抽象方法(强制覆写)
- 抽象类可以通过子类对象的向上转型实现类对象的实例化操作
对于抽象类的几个注意事项
注意一:抽象类定义的时候不能使用final关键字,因为抽象类必须有子类,而final定义的类不能有子类,这是矛盾的。
注意二:抽象类之中是能定义构造方法的,因为抽象类只是比普通类多一个抽象方法而已,其他结构(属性、全局常量、普通方法)全部存在,既然有属性了,那么一定要有构造方法。
注意三:抽象类之中可以没有抽象方法,但是此时依然无法直接产生抽象类的实例化对象。
问题四:抽象类使用关键字static分两种情况 ,一是:如果现在定义的是一个普通的外部类的话,那么无法使用关键字static来定义抽象类。二是:如果现在定义一个内部类,那么就可以使用static关键字了,因为使用static定义的内部类就成了一个外部类。
abstract class A{
public abstract void fun();
abstract static class B{ //内部抽象类
public abstract void print();
}
}
class X extends A.B{
public void print(){
System.out.println("Hello World.");
}
}
public class TextDemo12{
public static void main(String args[]){
A.B b = new X();
b.print();
}
}
输出结果为:Hello World。
注意五:一个抽象类的内部可以直接定义一个内部类继承抽象类
abstract class A{
public abstract void fun();
private static class X extends A{
public void fun(){
System.out.println("Hello World.");
}
}
public static A getInstance(){
return new X(); //X是A的子类
}
}
public class TextDemo12{
public static void main(String args[]){
A a =A.getInstance();
a.fun();
}
}
抽象类的应用
首先抽象类一定不是一个具体的类,他只是一个半成品,而子类负责实现这些未实现的功能。
例如:现在做这样一个程序分析,假设现在有三个按钮,每个按钮表示一种操作,而现在提供三种操作 吃饭、睡觉、工作,而现在又有三类事务:
- 机器 = 吃饭、工作
- 猪 = 吃饭、睡觉
- 人 = 工作、吃饭、睡觉
图解
代码如下
abstract class Action{
public static final int SLEEP = 1;
public static final int EAT = 5;
public static final int WORK = 10;
public abstract void eat();
public abstract void sleep();
public abstract void work();
public void command(int flag){
switch(flag){
case SLEEP :
this.sleep();
break;
case EAT :
this.eat();
break;
case WORK :
this.work();
break;
case SLEEP + EAT + WORK:
this.sleep();
this.eat();
this.work();
break;
case SLEEP + EAT:
this.sleep();
this.eat();
break;
case EAT + WORK:
this.eat();
this.work();
break;
default:
System.out.println("错误:未有此命令!");
}
}
}
class Robot extends Action{
public void eat(){
System.out.println("机器人在补充能量!");
}
public void sleep(){}
public void work(){
System.out.println("机器人在工作!");
}
}
class Pig extends Action{
public void eat(){
System.out.println("猪在进食!");
}
public void sleep(){
System.out.println("猪在睡觉");
}
public void work(){}
}
class Person extends Action{
public void eat(){
System.out.println("人在吃饭!");
}
public void sleep(){
System.out.println("人在睡觉!");
}
public void work(){
System.out.println("人在努力工作!");
}
}
public class TextDemo12{
public static void main(String args[]){
Action actA = new Robot();
actA.command(Action.WORK + Action.EAT);
Action actB = new Pig();
actB.command(Action.EAT + Action.SLEEP);
Action actC = new Person();
actC.command(Action.WORK + Action.EAT + Action.SLEEP);
}
}