本文旨在讨论什么时候使用抽象类,什么时候使用接口。
抽象类(Abstract):
我们知道Java面向对象编程中有继承的概念,当有的父类我们不希望可以创建其实例的时候就要用到抽象类。比如三角形、圆形、正方形的的父类都为“形状”,我们可以创建三角形、圆形和正方形的实例,但是不希望创建“形状”的实例,因为形状是不存在的,这个时候就要用到抽象的方法定义“形状”。
abstract class Shape{
abstract void draw();
abstract void erase();
}
值得注意的是:如果一个类有了一个抽象的方法,这个类就必须声明为抽象类。如果父类是抽象类,那么子类就必须覆盖所有在父类中的抽象方法,否则子类也将成为一个抽象类。
抽象类就是为了避免制造出这个类的对象而设计的。
接口(Interface):
Java把抽象的概念又更推进了一步,这就是接口,接口其实就是完全抽象的类。我们知道接口与抽象类的区别就是接口中所有的方法都是没有方法体的,而且都是public abstract类型的,接口中所有的成员变量都是public static final 的变量,并且必须经过定义初始化。
interface Shape{
void draw();
void erase();
}
下面我来总结一下:
1.抽象类和接口在某种程度上的确可以相互替换,比如上面这个例子。
2.抽象类只能被继承,且子类只能继承一个,而接口可以实现很多个。
3.如何选择使用抽象类还是接口取决于程序的设计,下面举个实例:
我们要实现一个“门”,其子类有木门,铁门,玻璃门:
我们用抽象类实现:
abstract class Door{
abstract void open();
abstract void close();
}
也可以用接口实现:
interface Door{
void open();
void close();
}
现在老板提出我们应该生产防盗门,并且安装在铁门和玻璃门上。
这个时候就会有个alarm()方法,但是显然alarm方法实现在Door抽象类中是不合理的,因为不是所有的门都有该方法。
在每个子类中添加alarm()方法也不合适,所以这个时候就应该使用接口,我们把程序重新设计一下:
abstract class Door{
abstract void open();
abstract void close();
}
interface Alarm {
void alarm();
}
class AlarmDoor extends Door implements Alarm {
void open() { … }
void close() { … }
void alarm() { … }
}
这样就完美了,如果老板现在让我们给木门和铁门加装猫眼的功能,只需要设计一个猫眼的接口就行了。
现在知道什么时候用抽象类什么时候用接口了吗?