介绍抽象类:
抽象类就是在普通方法的基础上扩充了一些抽象方法。
抽象方法指的是:只是声明但是并没有实现的方法。
所有抽象方法要用abstract来定义,并且抽象方法所在的类也要用abstract来定义为抽象类。
为什么要引用抽象类,一般类不就够用了吗。一般类里定义的方法,子类也可以覆盖,没必要定义成抽象的啊。
其实不是说抽象类有什么用,一般类确实也能满足应用,但是现实中确实有些父类中的方法确实没有必要写,因为各个子类中的这个方法肯定会有不同,所以没有必要再父类里写。当然你也可以把抽象类都写成非抽象类,但是这样没有必要。
而写成抽象类,这样别人看到你的代码,或你看到别人的代码,你就会注意抽象方法,而知道这个方法是在子类中实现的,所以,有个提示作用。
如何使用抽象类:
1.用向上转型实例化
abstract class Person{
private String name; // 属性
public String getName(){ // 普通方法
return this.name;
}
public void setName(String name){
this.name = name;
}
// {}为方法体,所有抽象方法上不包含方法体
public abstract void getPersonInfo(); //抽象方法
}
class Student extends Person{
public void getPersonInfo(){
System.out.println("I am a student");
}
}
abstract class Teacher expends Person{
//子类如果是抽象类可以不用覆写
public static int a;
}
public class Test{
public static void main(String[] args) {
Person per = new Student() ; //实例化子类,向上转型
per.getPersonInfo() ; //被子类所覆写的方法
}
}
2.在抽象类内部实现一个已经实例化好的子类
abstract class Person2{
public abstract void print();//抽象方法
//抽象类的静态普通方法
public static Person2 Instance(){
//局部内部类,继承了外部类后将他的抽象方法覆写
//在抽象类的内部实现一个已经实例化好的子类,可以选择用或者自己继承
class Student2 extends Person2{
public void print(){
System.out.print("Hello");
}
}
return new Student2();
}
}
public class Ex2 {
public static void main(String[] args) {
Person2 per = Person2.getInstance();
per.print();
}
}
抽象类的使用原则:
-
抽象必须有子类
(也就是说abstract与final,private不可以同时出现,因为被final修饰的类没有子类)
1.1 子类如果不是抽象类,则必须覆写抽象父类的所有方法。
1.2 子类如果是抽象类,那么可以不用覆写。 -
抽象类不能直接实例化对象,但是可以通过子类向上转型来实例化。
原因:因为抽象类中包含抽象方法,但是抽象方法没有方法体 ,也就是没有具体实现,所以抽象类不能直接产生实例化对象。(抽象类是个半成品)
使用抽象类的一些注意事项:
1.实例化子类的时候会默认先调用父类的构造方法再调用子类的构造方法。
abstract public void Person3{
public Person3(){
System.out.println("父类的构造方法");
}
public abstract void print3();
}
class Student3 extends Person3{
public Student3(){
System.out.println("子类的构造方法");
}
public void print3(){
System.out.println("Hello");
}
}
public class Ex3{
public static void main(String args[]){
Person3 person3 = new Student3();
person3.print3();
}
}
运行结果:
2.(日后详细更新)
abstract class Person4{
public Person4(){// 2
this.print4();// 3 调用父类的print4()方法
}
public abstract void print4();// 3 但是这个抽象的print4()方法没法用(抽象的用不了),所以回到子类
}
class Student4 extends Person4{
private int num = 100;//编译时实际为子类构造方法中的int num = 100;
public Student4(int num){ // 1 调用子类构造方法之前先调用父类构造方法↑
//super();//隐藏代码(编译以后编译器会自动加隐藏语句,先调父类的无参构造)
//int num = 100;//类中所有属性的初始化放到构造方法中,编译后实际是这样的
this.num = num;
}
public void print4(){ // 4 这个子类有被覆写,可以使用
System.out.println(this.num); // 5
}
}
public class Ex4 {
public static void main(String[] args) {
new Student4(30);
new Student4(30).print4();
}
}