Java为什么会出现抽象类,抽象类有什么作用,怎么理解抽象类,在什么时候使用抽象类?
简单来说:“抽象类就是接口和类的融合体。”,即三个臭皮匠顶一个诸葛亮,取长补短。(抽象类是继接口后的再一次升级。)
举个例子:先看此父类的最后一个没有方法体的方法
package com.javaeasy.learnabstractclass;// 包名
public class Person {// 类名
private String name;// 名字属性
public Person(String name) {// 构造方法
this.name = name;// 给name属性赋值
}
public String getName() {// 得到名字属性
return name;// 返回name属性
}
public void setName(String name) {// 设置name属性的方法
this.name = name;// 设置name属性的值
} // 介绍自己,在这里,因为不知道自己的具体身份,所以方法留空,子类应该覆盖此方法
public void introduceSelf() {
}
}
Person类中的方法introduceSelf()没有任何方法体,Person类中的方法introduceSelf()必须要被子类覆盖,否则的话调用introducesSelf()被执行是没有任何意义的,不应该被调用。
下面这个是一个子类,实现了父类的无方法体:introduceSelf()
package com.javaeasy.learnabstractclass; // 包名
public class Teacher extends Person {
// Teacher类继承了Person类
public Teacher (String name) {
// 构造方法
super(name); // 调用父类的构造方法
}
// 覆盖父类中的introduceSelf()方法,输出老师介绍自己的方法
public void introduceSelf() {
System.out.println("学生们好,我是一名老师,我的名字叫" + getName());
}
}
Person类的introduceSelf()是不能够被调用的,调用没有任何意义,只是因为子类要覆盖,所以父类必须有。在接口中抽象方法的作用:不能被调用,因为方法是抽象的,没有方法体,实现者必须提供此抽象方法的具体作用,咦? 这不正是Person类想要的吗?,所以呢,在Java中就允许在类中定义抽象方法,同时规定:当一个中有了抽象方法,他就必须是一个抽象类。 所以抽象类就是这么来的。(这段文字有点长如果真想学的话慢慢来。)
修改Person类之后的代码如下:
package com.javaeasy.learnabstractclass;// 包名
public abstract class Person {// 类名(1)变化1
private String name;// 名字属性
public Person(String name) {// 构造方法
this.name = name;// 给name属性赋值
}
public String getName() {// 得到名字属性
return name;// 返回name属性
}
public void setName(String name) {// 设置name属性的方法
this.name = name;// 设置name属性的值
} // 介绍自己,在这里,因为不知道自己的具体身份,所以方法留空,子类应该覆盖此方法
public abstract void introduceSelf();//(2)变化2
}
可以看见代码注释(1)(2)两个变化,(1)变化1:类名前用abstract修饰
(2)变化2:方法introduceSelf()用abstract修饰,并去掉方法体用分号(;)代替。注:抽象方法无法使用private修饰,因为子类要实现(也可以说覆盖)。
抽象类语法总结:
- 抽象类和接口一样不能使用new来创建其对象
- 抽象类中可以包含抽象方法,只要用abstract修饰就是抽象类,即使没有抽象方法(也就是说可以没有抽象方法)。
- 抽象类中的抽象方法不能使用private修饰,其他的都可以。
- 当一个类声明实现某个或者某些接口,但是却没有实现接口中定义的所以抽象方法时,那么这个类必须声明为抽象类。
- 使用extends继承它,子类也只能单继承,不能继承多个抽象类。
- 抽象类,它是一个类,它是抽象的,除了不能创建其实例,其余和类都一样。
总结一下抽象类的作用与抽象类和接口之间的区别:
(1)抽象类用来避免做一些不应该做的事情,(例如:Person中introduceSelf()不应该被调用。)
(2)抽象类在语法上通知子类应该覆盖某些方法,即:abstract修饰的方法(主要)。
(3)相比接口,抽象类中包括属性和方法,子类可以继承并使用它们,接口中只能包含抽象方法。如果将Person类完全改成接口那么每个子类都要重新添加属性,方法(不是抽象方法)如例子中的name属性,getname()方法,显而易见抽象类的好处。
参考书目------《一个老鸟的Java学习心得》