Many common interview questions ask questions such as what is the difference between an abstract class and an interface, when to use an abstract class and when to use an interface . In this article we will discuss these topics in detail.
Before discussing the differences between them, let's take a look at the characteristics of abstract classes and interfaces.
abstract class
Abstract classes are used to capture common features of subclasses. It cannot be instantiated and can only be used as a superclass of subclasses. Abstract classes are templates used to create subclasses in an inheritance hierarchy. Take GenericServlet in JDK as an example:
1
2
3
4
5
6
7
8
9
|
public
abstract
class
GenericServlet
implements
Servlet, ServletConfig, Serializable {
// abstract method
abstract
void
service(ServletRequest req, ServletResponse res);
void
init() {
// Its implementation
}
// other method related to Servlet
}
|
When the HttpServlet class extends GenericServlet, it provides the implementation of the service method:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
class
HttpServlet
extends
GenericServlet {
void
service(ServletRequest req, ServletResponse res) {
// implementation
}
protected
void
doGet(HttpServletRequest req, HttpServletResponse resp) {
// Implementation
}
protected
void
doPost(HttpServletRequest req, HttpServletResponse resp) {
// Implementation
}
// some other methods related to HttpServlet
}
|
interface
An interface is a collection of abstract methods. If a class implements an interface, then it inherits the abstract methods of that interface. It's like the contract pattern, if you implement this interface then you have to make sure to use these methods. An interface is just a form, an interface cannot do anything by itself. Take the Externalizable interface as an example:
1
2
3
4
5
6
|
public
interface
Externalizable
extends
Serializable {
void
writeExternal(ObjectOutput out)
throws
IOException;
void
readExternal(ObjectInput in)
throws
IOException, ClassNotFoundException;
}
|
When you implement this interface, you need to implement the above two methods:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
class
Employee
implements
Externalizable {
int
employeeId;
String employeeName;
@Override
public
void
readExternal(ObjectInput in)
throws
IOException, ClassNotFoundException {
employeeId = in.readInt();
employeeName = (String) in.readObject();
}
@Override
public
void
writeExternal(ObjectOutput out)
throws
IOException {
out.writeInt(employeeId);
out.writeObject(employeeName);
}
}
|
abstract class vs interface
parameter | abstract class | interface |
Default method implementation | It can have default method implementation | Interfaces are completely abstract. it doesn't have an implementation of the method at all |
accomplish | Subclasses use the extends keyword to inherit abstract classes. If the subclass is not an abstract class, it needs to provide implementations of all the methods declared in the abstract class. | Subclasses use the keyword implements to implement the interface. It needs to provide implementations of all declared methods in the interface |
Constructor | Abstract classes can have constructors | An interface cannot have a constructor |
Differences from normal Java classes | It is no different from a normal Java class except that you cannot instantiate an abstract class | Interfaces are completely different types |
access modifier | Abstract methods can have public , protected and default modifiers | 接口方法默认修饰符是public。你不可以使用其它修饰符。 |
main方法 | 抽象方法可以有main方法并且我们可以运行它 | 接口没有main方法,因此我们不能运行它。 |
多继承 | 抽象方法可以继承一个类和实现多个接口 | 接口只可以继承一个或多个其它接口 |
速度 | 它比接口速度要快 | 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 |
添加新方法 | 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 | 如果你往接口中添加方法,那么你必须改变实现该接口的类。 |
什么时候使用抽象类和接口
- 如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。
- 如果你想实现多重继承,那么你必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。
- 如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。
Java8中的默认方法和静态方法
Oracle已经开始尝试向接口中引入默认方法和静态方法,以此来减少抽象类和接口之间的差异。现在,我们可以为接口提供默认实现的方法了并且不用强制子类来实现它。这类内容我将在下篇博客进行阐述。