Java中抽象类和具体类的区别
抽象类 :抽象类是Java中由 abstract
关键字声明的类类型。 抽象类不能直接实例化,即此类的对象不能直接使用 new
关键字创建。 抽象类可以通过具体子类或通过定义所有抽象方法以及新语句来实例化。 它可能包含也可能不包含抽象方法。 抽象方法由 abstract
关键字声明,此类方法不能有主体。 如果一个类包含一个抽象方法,那么它也需要是抽象的。
具体类 :Java中的具体类是一种子类,它实现了它所扩展的超抽象类的所有抽象方法。 它还实现了它实现的所有接口方法。
抽象类与具体类
修饰符 :使用抽象修饰符声明抽象类。不使用 abstract
关键字声明具体类,如果使用 abstract
声明,那么它也将成为一个抽象类。
实例化 :不能直接实例化抽象类,即不能使用 new
关键字直接创建该类的对象。 抽象类可以通过具体子类或通过定义所有抽象方法以及新语句来实例化。 可以使用 new
关键字直接实例化具体类。
示例: 抽象类的无效直接实例化。
abstract class DemoAbstractClass {
abstract void display();
}
public class JavaApplication {
public static void main(String[] args)
{
DemoAbstractClass AC = new DemoAbstractClass();
System.out.println("Hello");
}
}
编译错误:
prog.java:9: error: DemoAbstractClass is abstract; cannot be instantiated
DemoAbstractClass AC = new DemoAbstractClass();
示例: 通过定义抽象类的所有抽象方法来有效实例化。
abstract class DemoAbstractClass {
abstract void display();
}
public class JavaApplication {
public static void main(String[] args)
{
DemoAbstractClass AC = new DemoAbstractClass() {
void display()
{
System.out.println("Hi.");
}
};
AC.display();
System.out.println("How are you?");
}
}
运行结果:
Hi.
How are you?
示例 :使用 new
关键字直接实例化。
abstract class DemoAbstractClass {
abstract void display();
}
class ConcreteClass extends DemoAbstractClass {
void display()
{
System.out.println("Hi.");
}
}
public class JavaApplication {
public static void main(String[] args)
{
ConcreteClass C = new ConcreteClass();
C.display();
System.out.println("How are you?");
}
}
运行结果:
Hi.
How are you?
1、抽象方法: 抽象类可能有也可能没有抽象方法。具体类不能有抽象方法,因为包含抽象方法的类也必须是抽象的。
下面通过一个例子来理解:
在 Servlet 中有一个名为“HttpServlet”的类。 现在,这个类有它自己的特别之处。“HttpServlet 是一个抽象类,但它不包含任何抽象方法”。
深入理解上述语句的含义:
- 如果方法没有正确的实现,那么为什么他们没有把它抽象化呢?
-> 由于抽象方法是那些没有正确定义主体的方法,因此我们在类中重写此类方法以对其进行正确定义。 所以基本上抽象方法用于覆盖目的。
现在这个“HttpServlet”类包含10个方法,假设如果这些方法是抽象的,那么我们需要覆盖“HttpServlet”类的所有10个方法,这是一种愚蠢的方式,因为只需要doGet()
和doPost()
方法。 -
public void service(ServletRequest req, ServletResponse res)
-
protected void service(HttpServletRequest req, HttpServletResponse res)
- protected void doGet(HttpServletRequest req, HttpServletResponse res)
- protected void doPost(HttpServletRequest req, HttpServletResponse res)
- protected void doHead(HttpServletRequest req, HttpServletResponse res)
- protected void doOptions(HttpServletRequest req, HttpServletResponse res)
- protected void doPut(HttpServletRequest req, HttpServletResponse res)
- protected void doTrace(HttpServletRequest req, HttpServletResponse res)
- protected void doDelete(HttpServletRequest req, HttpServletResponse res)
- protected void getLastModified(HttpServletRequest req)
2、final :抽象类不能是 final
,因为它的所有抽象方法都必须在子类中定义。一个具体的类可以声明为 final
。
3、interface :抽象类不能单独实现接口,但它可以通过使用子类来实现接口,而不提供接口所有方法的实现。 以抽象类为祖先的第一个具体类负责实现接口中的所有方法。
抽象类 | 具体类 |
---|---|
抽象类是使用抽象修饰符声明的。 | 不使用抽象修饰符声明具体类。 |
抽象类不能使用 new 关键字直接实例化。 |
可以使用 new 关键字直接实例化具体类。 |
抽象类可能包含也可能不包含抽象方法。 | 具体类不能包含抽象方法。 |
抽象类不能声明为 final 。 |
一个具体的类可以声明为 final 。 |
通过不提供所有接口方法的实现来实现接口是可能的。 为此,需要一个子类。 | 接口中所有方法的简单实现。 |
一些重要的点 :
- 具体类是抽象类的子类,它实现了它的所有抽象方法。
- 抽象方法不能有主体。
- 抽象类可以像其他类一样具有静态字段和静态方法。
- 抽象类不能声明为
final
。 - 只有抽象类可以有抽象方法。
private
,final
,static
的方法不能是抽象的,因为它不能在子类中被覆盖。- 抽象类不能有抽象构造函数。
- 抽象类不能有抽象静态方法。
- 如果一个类扩展了一个抽象类,那么它应该定义基本抽象类的所有抽象方法(覆盖)。 如果不是,子类(扩展抽象类的类)也必须定义为抽象类。