一.抽象方法
说抽象方法之前我们先来看一个多态的例子:
//父类
public class Mammal {
public void move() {
System.out.println("正在移动、、、");
}
}
//子类
public class Whale extends Mammal{
public void move() {
System.out.println("鱼鳍游动、、、");
}
}
public class Earth {
public static void main(String[] args) {
Mammal mammal=new Whale();
mammal.move();
}
}
因为mammal变量类型是Mammal类,所以表面上调用的是Mammal类中的方法;但因为mammal变量保存了new Whale()地址,所以再程序运行时JVM根据地址找到new Whale(),实质是new Whale().move(),即运行时调用的是子类重写的方法 即多态。
这时我们会发现,父类的的move方法因为被子类重写了,所以在多态中没有了实质性的作用,这时如果我们把父类中move方法的方法体去掉,在void前面加上abstract修饰符,move方法就叫做抽象方法:
public abstract void move();
二.抽象类
当一个普通类中存在上述的抽象方法时,这个类就叫做抽象类,在class前加abstract修饰符,如下:
//父类
public abstract class Mammal {
public abstract void move();
}
三.抽象类的特性
1.构造方法
抽象类是有默认构造方法的,当我们在抽象类中定义一个无参构造方法时,它是不会报错的,就像这样:
//父类
public abstract class Mammal {
public Mammal() {
}
public abstract void move();
}
2.创建对象
抽象类虽然有默认构造方法,但是却不能创建对象,像下面这段代码在Test类中创建一个Mammal类的对象,由于Mammal是抽象类,所以便会报错:
//父类
public abstract class Mammal {
public abstract void move();
}
public class Test {
public static void main(String[] args) {
Mammal mammal=new Mammal();
}
}
3.无抽象方法也可
抽象类中不仅可以有其他方法,就算没有抽象方法都是合法的,但是一旦有了抽象方法,如果不定义成抽象类就是不合法的:
//父类
public abstract class Mammal {
public void move() {
System.out.println("moving...");
}
public void eat() {
System.out.println("eating...");
}
}
4.抽象类的子类
当父类为抽象类时,子类如果没有将父类中的所有抽象方法都重写,则该子类必须是抽象类,因为如果存在父类的抽象方法未被子类重写,则就会被子类继承,这时就相当于子类中也存在了抽象方法,所以子类必须是抽象类:
//父类
public abstract class Mammal {
public abstract void move();
public abstract void eat();
}
//子类
public abstract class Whale extends Mammal{//如果不定义为抽象类则会报错
@Override
public void move() {
System.out.println("鱼鳍游动、、、");//只重写了父类的抽象方法的其中一个
}
}
四.抽象类与普通类的区别
a、抽象类有abstract修饰 普通类没有
b、抽象类不能创建对象,普通类可以创建对象
c、抽象类中可以有抽象方法,普通类绝对不能有抽象方法
五.抽象类使用时的注意
1.抽象类前不能加final修饰符,因为如果抽象类前面可以添加final就意味着该类无法被继承,也就意味着该抽象类中的抽象方法永远无法得到实现,也就意味着抽象类中的抽象方法是无用的。
2.抽象类中的抽象方法不能用private修饰符,因为被private修饰的方法其作用范围为本类,如果抽象类中的抽象方法被private修饰就意味着该方法永远无法被实现。
3.抽象类中的抽象方法不能用static修饰,因为抽象类中的抽象方法如果可以被static修饰就意味着可以使用抽象类的类名来使用该方法,但是该抽象方法没有方法体,不具有使用的价值,所以Java中规定抽象类中不能包含被static修饰的静态抽象方法。
以下是这三种错误的使用方法:
//父类
public final abstract class Mammal {//final修饰不能被继承
private abstract void move();//private修饰的方法不能被重写
public static abstract void eat();//static修饰无价值
}