抽象类:抽象类是Java中的一种类,由abstract关键字声明。抽象类不能直接实例化,即不能直接使用 new 关键字创建此类的对象。抽象类可以通过具体子类或通过定义所有抽象方法以及 new 语句来实例化。它可能包含也可能不包含抽象方法。抽象方法由abstract关键字声明,这样的方法不能有主体。如果一个类包含一个抽象方法,那么它也需要是抽象的。
具体类: Java中的具体类是一种子类,它实现了它所扩展到的超抽象类的所有抽象方法。它还具有它实现的所有接口方法的实现。
抽象类与具体类
- 修饰符:使用抽象修饰符声明抽象类。不应使用抽象关键字声明具体类,否则它也会成为抽象类。
- 实例化:抽象类不能直接实例化,即不能直接使用new关键字创建该类的对象。抽象类可以通过具体子类或通过定义所有抽象方法以及 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?
- 抽象方法:抽象类可能有也可能没有抽象方法。具体类不能有抽象方法,因为包含抽象方法的类也必须是抽象的。
让我们通过一个例子来理解这一点:-
我们在 Servlet 中有一个名为“HttpServlet”的类。现在,这个类有自己的特殊性。
“HttpServlet 是一个抽象类,但它不包含任何抽象方法”。
让我们深入理解上述语句的含义:-
-> HttpServlet 是一个抽象类,因为它的方法没有正确的实现。既然它的方法没有正确的实现,那么为这样的类创建对象有什么意义。因此,这个类是抽象的。现在出现的问题是:-
问:如果方法没有正确的实现,那为什么不把它抽象化?
-> 因为抽象方法是那些没有适当的主体定义的方法,我们在我们的类中覆盖这些方法来给它一个适当的定义。所以基本上抽象方法用于覆盖目的。
现在这个“HttpServlet”类包含 10 个方法,假设如果这些方法是抽象的,那么我们需要覆盖“HttpServlet”类的所有 10 个方法,这是一种愚蠢的方法,因为我们只需要 doGet() 和 doPost() 方法。下面是一个示例程序,用于在Java说明上述观点:
// Java program to show servlet example // Importing required Java libraries import java.io.*; import javax.servlet.*; import javax.servlet.http.*; // Extend HttpServlet class public class AdvanceJavaConcepts extends HttpServlet { private String output; // Initializing servelet public void init() throws ServletException { output = "Advance Java Concepts"; } // Requesting and printing the output public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println(output); } public void destroy() { System.out.println("Over"); } }
输出:
Advance Java Concepts output Over
注意:如前所述,HttpServlet 类不包含任何抽象方法。因此程序成功运行而不会覆盖其所有方法。
但是假设如果这个类包含它所有的抽象方法,那么我们需要覆盖它的所有方法,尽管它们在我们的类中什么都不做。
HttpServlet 类的方法原型为:- 公共无效服务(ServletRequest req, ServletResponse res)
- 受保护的无效服务(HttpSerletRequest req,HttpServletResponse res)
- protected void doGet(HttpSerletRequest req, HttpServletResponse res)
- protected void doPost(HttpSerletRequest req, HttpServletResponse res)
- protected void doHead(HttpSerletRequest req, HttpServletResponse res)
- protected void doOptions(HttpSerletRequest req, HttpServletResponse res)
- protected void doPut(HttpSerletRequest req, HttpServletResponse res)
- protected void doTrace(HttpSerletRequest req, HttpServletResponse res)
- protected void doDelete(HttpSerletRequest req, HttpServletResponse res)
- protected void getLastModified(HttpSerletRequest req)
如果我们的类是抽象的,那么这些方法的不必要覆盖就会出现在我们的类中。
注意:但是在 NetBeans 等最新的 IDE 中,它会自动覆盖所有抽象方法,为它们提供空白主体,减少程序员重写的麻烦。
- Final:抽象类不能是final ,因为它的所有抽象方法都必须在子类中定义。具体类可以声明为final 。
- 接口:抽象类不能单独实现接口,但可以通过使用子类而不提供接口所有方法的实现来实现接口。以抽象类为祖先的第一个具体类负责实现接口中的所有方法。
Abstract Class | Concrete Class |
---|---|
An abstract class is declared using abstract modifier. | A concrete class is note declared using abstract modifier. |
An abstract class cannot be directly instantiated using the new keyword. | A concrete class can be directly instantiated using the new keyword. |
An abstract class may or may not contain abstract methods. | A concrete class cannot contain an abstract method. |
An abstract class cannot be declared as final. | A concrete class can be declared as final. |
Implement an interface is possible by not providing implementations of all of the interface’s methods. For this a child class is needed.. | Easy implementation of all of the methods in the interface. |
一些要点:
- 具体类是抽象类的子类,抽象类实现了它的所有抽象方法。
- 抽象方法不能有主体。
- 抽象类可以像其他类一样有静态字段和静态方法。
- 抽象类不能声明为 final。
- 只有抽象类可以有抽象方法。
- 私有的、最终的、静态的方法不能是抽象的,因为它不能在子类中被覆盖。
- 抽象类不能有抽象构造函数。
- 抽象类不能有抽象静态方法。
- 如果一个类扩展了一个抽象类,那么它应该定义基础抽象类的所有抽象方法(覆盖)。如果不是,则子类(扩展抽象类的类)也必须定义为抽象类。