abstract修饰符可用来修饰类和成员方法。
- 用abstract修饰的类叫抽象类,抽象类不能被实例化。没有用abstract修饰的类叫具体类,具体类可以被实例化。
- 用abstract修饰的方法叫抽象方法,抽象方法没有方法体。没有用abstract修饰的方法称为具体方法,具体方法具有方法体
注意没有方法体是没有{}的
public abstract void call();//没有方法体 public void eat(){}//有方法体,空实现
看下面的这个抽象类的例子:
abstract class Animal {
public abstract void call();
public abstract void move();
}
class Dog extends Animal {
public void call() {
System.out.println("汪汪汪!");
}
public void move() {
System.out.println("跑");
}
}
abstract class Bird extends Animal {
public void move() {
System.out.println("飞");
}
}
public class Test {
public static void main(String[] args) {
Bird bird = new Bird() {
@Override
public void call() {
System.out.println("叽叽叽");
}
};
bird.move();
bird.call();
}
}
使用abstract修饰符的时候需要遵守以下语法规则:
-
抽象类中可以没有抽象方法,包是包含了抽象方法的类必须定义为抽象类。如果子类没有实现父类中的所有抽象方法,那么子类也必须定义为抽象类。比如上述Bird类。如果Bird类没有用abstract修饰会报错。
-
抽象类不能用final修饰符修饰。这个其实也好理解,因为我们都知道final修饰的类不允许被继承,final修饰的方法不允许被覆盖。而abstract修饰的类只允许创建子类,它的抽象方法才会被实现。所以abstract和final连用会自相矛盾。
-
abstract不能和static连用,没有抽象静态方法。我们都知道static在类被加载的时候就会被执行,可以直接通过类名来访问。而抽象方法是没有方法体的,连用的话也完全没有意义。在一起使用的话会编译出错,但是抽象类中可以用静态方法。比如:
abstract class Bird extends Animal { public void move() { System.out.println("飞"); } static void eat() { System.out.println("吃虫子"); } }
-
抽象方法不能被private修饰。这是因为如果方法是抽象的,肯定是要子类来实现它的,所以如果是private修饰的话,子类是无法访问的。假如两者能连用,就意味着父类中申明了一个永远无法实现的方法。这完全没有必要。
-
抽象类中可以有非抽象的构造方法,创建子类的时候可能会调用这些构造方法。抽象类不能被实例化,然而可以创建一个引用变量,其类型是一个抽象类,并让他引用非抽象类的一个实例。比如还是上述代码的例子,我可以这样写:
Animal animal = new Dog(); animal.call(); animal.move();
网友评论