Java 抽象类
Java 中有一个叫做抽象方法的机制,它只有声明而没有方法体:
abstract void functionName();
包含抽象方法的类叫做抽象类。如果一个类包含一个或多个抽象方法,那么这个类就必须限定为抽象类,否则编译器会报错。
abstract class ClassName {
abstract void functionName();
}
抽象类不能被直接实例化:
ClassName c = new ClassName(); // 编译器会报错
如果创建一个继承抽象类的新类,那么必须为它父类的所有抽象方法提供定义,如果不这么做,这个新类仍然是一个抽象类,编译器会强制我们为新类加上abstract关键字。
可以将一个不包含任何抽象方法的类声明为抽象类,这样做虽然有点别扭,但是它可以实现不能被实例化的特性。
总结起来,抽象类有以下三类:
- 仅包含抽象方法
- 既包含抽象方法又包含常规方法
- 仅包含常规方法,不包含抽象方法
一个简单的示例:
public class AbstractClassTest {
public static void main(String[] args)
{
Bmw myCar = new Bmw();
myCar.illuminate();
myCar.soundWhistle();
}
}
abstract class Car {
/**
* 鸣笛
* 不同的汽车对于实现鸣笛的方式不同
*/
abstract void soundWhistle();
/**
* 灯光
* 每个车的灯光是一样的
*/
public void illuminate()
{
System.out.println("Light On!");
}
}
class Bmw extends Car {
@Override
void soundWhistle() {
System.out.println("Bee Bee!");
}
}
为什么需要抽象类和抽象方法呢?
抽象方法和抽象类看上去是多余的,对于抽象方法,不知道如何实现,定义一个空方法体不就行了吗,而抽象类不让创建对象,看上去只是增加了一个不必要的限制。
引入抽象方法和抽象类,是Java提供的一种语法工具,对于一些类和方法,引导使用者正确使用它们,减少被误用。
使用抽象方法,而非空方法体,子类就知道他必须要实现该方法,而不可能忽略。
使用抽象类,类的使用者创建对象的时候,就知道他必须要使用某个具体子类,而不可能误用不完整的父类。
就好比定义了一个模板,你需要遵守规则的情况下来设计代码。
另外,送上在java - Can we instantiate an abstract class? - Stack Overflow看到的一个问题,抽象类真的不能被实例化吗?
abstract class my {
public void mymethod() {
System.out.print("Abstract");
}
}
class poly {
public static void main(String a[]) {
my m = new my() {};
m.mymethod();
}
}
按照那个链接中网友所说的,这里的m并不是严格意义上的抽象类实例化,而是实例化了抽象类的匿名子类。
对象的实例化应该是new ClassName();,分号在()之后,而不是在{}之后,那样的话是实例化了一个匿名类(anonymous class)。
抽象类和接口
抽象类和接口有类似之处,都不能用于创建对象,接口中的方法其实都是抽象方法。如果抽象类中只定义了抽象方法,那抽象类和接口就更像了。但抽象类和接口根本上是不同的,一个类可以实现多个接口,但只能继承一个类。
抽象类和接口是配合而非替代关系,它们经常一起使用,接口声明能力,抽象类提供默认实现,实现全部或部分方法,一个接口经常有一个对应的抽象类。
参考来源: