1 抽象类基本概念
类继承的主要作用在于可以扩充已有类的功能,但是对于之前的继承操作而言,子类可以有自己的选择决定是否要腹泻某一方法,这个时候父类无法对子类做出强制性约定(强制性你必须覆写某些方法),这个时候往往不使用类的继承(在实际的开发之中很少会出现继承一个已经完善的类,可以直接使用的类,而是必须要继承抽象类)。在以后进行父类(Super class)设计的时候优先考虑的一定是抽象类。
抽象类的主要作用在于对子类中覆写方法进行约定,在抽象类里面可以去定义一些抽象方法以实现这样的约定,抽象方法指的是使用了abstract关键字定义的并且没有提供方法体的方法,而抽象方法所在的类必须为抽象类,抽象类必须使用abstract关键字来进行定义(在普通类的基础上追加抽象方法就是抽象类)。
当一个抽象类定义完成之后,(切记:抽象类不是完整的),如果要使用抽象了,要使用以下原则:
(1)抽象类必须提供有子类,子类使用extends继承一个抽象类;
(2)抽象类的子类(不是抽象类)一定要覆写抽象类中的全部抽象方法;
(3)抽象类的对象实例化可以利用多态性通过子类向上转型的方式完成。
从整体上来讲,抽象类只是比普通方类增加了抽象方法以及对子类的强制性的覆写要求而已,其它的使用过程和传统的类继承是完全相同。
对与抽象类使用的几点意见:
(1)抽象类的使用很大程度上有一个核心的问题:抽象类自己无法直接实例化;
(2)抽象类之中主要的目的是进行过渡操作使用,所以当你要使用抽象类进行开发的时候,往往都是在你设计中需要解决类继承问题时所带来的代码重复处理。
2 抽象类的相关说明
使用抽象类注意事项:
(1)在定义抽象类的时候绝不能使用final关键字来进行定义,因为抽象类必须有子类,而final定义的类不能够有子类。
final abstract class Action{
}
/*
PS D:\Program Files\EditPlus\java> javac JavaDemo.java
JavaDemo.java:1: 错误: 非法的修饰符组合: abstract和final
final abstract class Action{
^
1 个错误
*/
(2)抽象类是作为一个普通类的加强版出现的(抽象类的组成就是在普通类的基础上扩展而来的,只是追加了抽象方法。既然是在普通类基础上扩展的,那么普通类之中就可以定义属性和方法,那么这些属性一定是要求进行内存空间开辟的,所以抽象类可以提供有构造方法,并且子类也一定会按照子类对象的实例化原则进行父类构造调用。
(3)抽象类允许没有抽象方法,但是即便没有抽象方法,也无法直接使用关键字new直接实例化抽象类对象。即便抽象类没有实例化对象,那么也无法直接使用关键字new获取抽象类的对象,必须依靠子类对象完成。
abstract class Action{
}
public class JavaDemo{
public static void main(String[] args){
Action act = new Action();
}
}
/*
PS D:\Program Files\EditPlus\java> javac JavaDemo.java
JavaDemo.java:7: 错误: Action是抽象的; 无法实例化
Action act = new Action();
^
1 个错误
*/
abstract class Action{
}
class PersonAction extends Action{
}
public class JavaDemo{
public static void main(String[] args){
Action act = new PersonAction();
}
}
(4)抽象类可以提供有static方法,并且该方法不受到抽象类对象的局限。static方法永远不受到实例化对象或结构的限制,永远可以直接通过类名称进行调用。
abstract class Action{
public static void print(){
System.out.println("hello");
}
}
class PersonAction extends Action{
}
public class JavaDemo{
public static void main(String[] args){
Action act;
Action.print();
}
}
3 模板设计模式
抽象类的本质就属于一个加强型的类,那么对于类已经清楚了,可以描述一切的有关的现实事物,但是通过分析我们也可以发现,抽象类的设计应该是比类更高一层的定义。
abstract class Action{
public static final int SLEEP = 1;
public static final int EAT = 5;
public void command(int comm){
switch(comm){
case SLEEP:{
this.sleep();
break;
}
case EAT: {
this.eat();
break;
}
}
}
public abstract void sleep();
public abstract void eat();
}
class PersonAction extends Action{
public void sleep(){
System.out.println("man sleep!");
}
public void eat(){
System.out.println("man eat!");
}
}
class PigAction extends Action{
public void sleep(){
System.out.println("pig sleep!");
}
public void eat(){
System.out.println("pig eat!");
}
}
public class JavaDemo{
public static void main(String[] args){
Action personact = new PersonAction();
Action pigact = new PigAction();
personact.command(1);
personact.command(5);
pigact.command(1);
pigact.command(5);
}
}
现在程序已经完整的实现了一个行为的抽象处理,但是也需要做出一点点思考。现在定义的Action父类主要的目的是为了对所有行为规范进行统一处理。
抽象类最大的好处一是对子类方法的统一管理,二是可以自身提供有一些普通方法,并且这些普通方法可以调用抽象方法(这些抽象方法必须有子类提供实现的时候才会生效)。