1、什么是抽象类
普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法、普通方法、static方法、常量和变量等内容。而抽象类是指在普通类的结构里面增加抽象方法的组成部分。
那么什么叫抽象方法呢?在所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰。
而拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明。如果一个类包含抽象方法,那么该类必须是抽象类。注意:抽象类不一定有抽象方法,但是有抽象方法的类必须定义成抽象类。
abstract class A{//定义一个抽象类
public void fun(){//普通方法
System.out.println("存在方法体的方法");
}
public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}
2、抽象类的使用
首先,我们要知道抽象类是无法实例化对象的。无法直接进行实例化操作。为什么不能直接实例化呢?当一个类实例化之后,就意味着这个对象可以调用类中的属性或者放过了,但在抽象类里存在抽象方法,而抽象方法没有方法体,没有方法体就无法进行调用。既然无法进行方法调用的话,又怎么去产生实例化对象呢。
那么我们究竟要怎么使用我们的抽象类呢?
抽象类的使用原则如下:
(1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
(2)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;
(3)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;
(4)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。);
abstract class A{//定义一个抽象类
public void fun(){//普通方法
System.out.println("存在方法体的方法");
}
public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}
//单继承
class B extends A{//B类是抽象类的子类,是一个普通类
@Override
public void print() {//强制要求覆写
System.out.println("Hello World !");
}
}
public class TestDemo {
public static void main(String[] args) {
A a = new B();//向上转型
a.print();//被子类所覆写的过的方法
}
}
以上代码输出结果为
Hello World !
那么我们就知道,在我们的一个普通类去继承我们的抽象类的时候,会被强制要求重写抽象类中的抽象方法,如果不重写,那就只能把子类也定义为抽象类。
3、抽象类存在的意义
1、抽象类就是为了被子类继承。(就是为了派生子类),否则毫无意义。
2、抽象类体现的是模板思想,部分实现,部分抽象。可以设计模板设计模式。
那么何为模设计模板呢?
设计模式是前人或者技术大牛或者软件行业在实战中发现的优秀软件设计架构和思想。
后来者可以直接用这些架构或者思想就可以设计出优秀、高效率、可扩展性好和可维护性好的软件。
模板设计模式就是一种经典的设计模式思想。
模板设计模式的作用:优化代码架构,提高代码的复用性。
我们现在使用抽象类设计一个模板模式的应用,例如在小学的时候,我们经常写作文,通常都是有模板可以套用的。
当在继承关系中设计父类的时候,如果父类中的一个公共方法父类不确定该方法的具体实现,那么父类就干脆不实现,将其定义成抽象方法,让子类自己去实现。
假如我现在需要定义新司机和老司机类,新司机和老司机都有开车功能,开车的步骤都一样,只是驾驶时的姿势有点不同,新司机:开门,点火,双手紧握方向盘,刹车,熄火
,老司机:开门,点火,右手握方向盘左手抽烟,刹车,熄火
。我们可以将固定流程写到父类中,不同的地方就定义成抽象方法,让不同的子类去重写,代码如下:
// 司机开车的模板类
public abstract class Driver {
public void go() { //模板方法:具体定义了固定的流程
System.out.println("开门");
System.out.println("点火");
// 开车姿势不确定?定义为抽象方法
ziShi();
System.out.println("刹车");
System.out.println("熄火");
}
public abstract void ziShi();
}
现在定义两个使用模板的司机:
public class NewDriver extends Driver {
@Override
public void ziShi() {
System.out.println("新司机双手紧握方向盘");
}
}
public class OldDriver extends Driver {
@Override
public void ziShi() {
System.out.println("老司机右手握方向盘左手抽烟...");
}
}
编写测试类
public class Demo02 {
public static void main(String[] args) {
NewDriver nd = new NewDriver();
nd.go();
OldDriver od = new OldDriver();
od.go();
}
}
可以看出,模板模式的优势是,模板已经定义了通用架构,使用者只需要关心自己需要实现的功能即可!非常的强大!