1. 抽象基础
随着继承中子类的不断增多,子类变的越来越具体,父类变得越来越抽象,以至于不再在乎父类的实例。因此,有时将父类完全抽象化,让他没有任何实例来实现,只有子类,这种父类就叫做 抽象类
使用 abstract 修饰符来表示一个 类、方法 是抽象的。
【abstract 类】
- 该类无法被实例化
- 抽象类中一定有构造器,便于子类实例化时调用
- 开发中,都会提供抽象类的子类,让子类对象实例化,来调用抽象类中的方法
【abstract 方法】
- 只用方法声明,没有方法体
- 抽象方法只能存在于抽象类中,实体类不能含有抽象方法。
- 但是抽象类可以含有实体方法。
- 实体子类必须重写抽象父类的抽象方法。
- 只有子类重写了父类中所有的抽象方法后,此子类方可实例化。反之,一旦有没重写的抽象方法,该子类必须要是抽象类。
- 子类要重写父类的抽象方法,也要重写父类的父类的抽象方法,以此类推,子类要重写所有父类的所有抽方法。
【abstract 其他要注意的地方】
- abstract 不能 用来修饰 属性、构造器 等结构
- abstract 不能 用来修饰 私有方法(private)、静态方法(static)、final 方法、final的类
- 静态方法没有重写
- final方法不能被重写
- final类无法被继承
2. 抽象的应用
抽象类是用来模型化那些父类无法确定全部实现,而是由其子类提供具体实现的对象的类
比如,在交通系统中,有卡车Truck、驳船RiverBarge、飞机Plane 等等,他们共同属于一个父类 Vehicle,交通工具都具有计算燃油、里程的功能,但是每个交通工具的计算方法又不一样,因此父类完全不能确定相关方法的方法体。这是 Vehicle 就可以声明为抽象类,对应的方法声明为抽象方法,没有方法体,让子类来自己重写对应的方法即可。
这样来看,抽象还是有些鸡肋。实际上,在开发中并不经常使用到抽象,而是用更进一步的接口来完成上述功能,这个在后续会讲到。
3. 匿名子类
现有一个抽象类 Person,形式如下:
package pkg4;
public abstract class Person {
private String name ;
private int age ;
public abstract void eat();
public abstract void talk();
}
很显然,下述的写法是错误的,抽象类无法被实例化:
package pkg4;
public class AbstractTest {
Person p1 = new Person() ; // ERROR
}
但是,我们可以构造一个重写了 Person 所有方法的子类的对象,不过只知道对象名而不知道子类的名称,格式如下所示:<br /><br />匿名子类的对象创建可以说是结合了 多态性,即左边是抽象父类,但右边 new 出来的是实现了抽象方法的匿名子类。