Java 没有抽象方法时为什么要标记类抽象

Java 没有抽象方法时为什么要标记类抽象,java,oop,abstract-class,Java,Oop,Abstract Class,我对java中的抽象类有点困惑。我知道,每当类编译器中有抽象方法时,开发人员都会强制标记类抽象。但是,即使我们在类中没有任何抽象方法,我们仍然将整个类标记为抽象的。我不明白为什么我们可以这样做。当没有抽象方法时,允许开发人员标记类抽象的目的是什么。可以说,原因是我们不想创建该类的实例。如果是这个原因,那么将类的构造函数标记为private比将类标记为abstract更合适。我认为这是允许创建子类,而不是创建主类。 我猜您的类中有方法存根,否则就没有理由不实例化它。一般来说,使用抽象方法更好。我认

我对java中的抽象类有点困惑。我知道,每当类编译器中有抽象方法时,开发人员都会强制标记类抽象。但是,即使我们在类中没有任何抽象方法,我们仍然将整个类标记为抽象的。我不明白为什么我们可以这样做。当没有抽象方法时,允许开发人员标记类抽象的目的是什么。可以说,原因是我们不想创建该类的实例。如果是这个原因,那么将类的构造函数标记为private比将类标记为abstract更合适。

我认为这是允许创建子类,而不是创建主类。
我猜您的类中有方法存根,否则就没有理由不实例化它。一般来说,使用抽象方法更好。

我认为允许创建子类,但不允许创建主类。
我猜您的类中有方法存根,否则就没有理由不实例化它。通常最好使用抽象方法来实现这一点。

用于限制要实例化的类。。示例
HttpServlet
class。。它定义为抽象,但没有
抽象方法
。。我们可以在子类中使用这些方法,但是创建类httpservlet本身是无用的。。这就是我认为的原因


用于限制要实例化的类。。示例
HttpServlet
class。。它定义为抽象,但没有
抽象方法
。。我们可以在子类中使用这些方法,但是创建类httpservlet本身是无用的。。这就是我认为的原因

可以说,原因是我们不想创建 那个班。如果这是原因,则标记类的构造函数 private比将类标记为抽象更合适

这根本不合适

下面的示例将消除您的疑虑,如果您使用私有构造函数,不仅会阻止对象创建,而且您甚至无法创建父类的子类

    class ParentClass{
             private ParentClass(){

             }
   }
    class Subclass extends ParentClass{
    static{
    System.out.println("Hello");
    }

  }
您将得到编译时错误消息

error: ParentClass() has private access in ParentClass
但是
将类标记为
抽象将阻止对象创建,但不会阻止java中的继承


更新

正如您在评论中所要求的,您可以将其设置为受保护的,但这样您的类就可以很容易地实例化,因为
受保护的
成员可以从
同一类
以及同一包
中的
子类以及另一包中的
子类中访问

可以说,原因是我们不想创建 那个班。如果这是原因,则标记类的构造函数 private比将类标记为抽象更合适

这根本不合适

下面的示例将消除您的疑虑,如果您使用私有构造函数,不仅会阻止对象创建,而且您甚至无法创建父类的子类

    class ParentClass{
             private ParentClass(){

             }
   }
    class Subclass extends ParentClass{
    static{
    System.out.println("Hello");
    }

  }
您将得到编译时错误消息

error: ParentClass() has private access in ParentClass
但是
将类标记为
抽象将阻止对象创建,但不会阻止java中的继承


更新


正如您在评论中所要求的,您可以将其设置为受保护的,但这样您的类就可以很容易地实例化,因为可以从
同一类
以及同一包
中的
子类以及另一包中的
子类
中访问
成员,这可能是为了防止实例化。我非常喜欢私有或受保护的构造函数,因为我觉得它们更清楚地传达了意图


此外,在类层次结构中,如果
类a
是抽象的并且包含抽象方法,则不需要在扩展
类a
类B
中定义该方法。在这种情况下,
类B
被标记为抽象,并且没有抽象成员。

如上所述,这可以防止实例化。我非常喜欢私有或受保护的构造函数,因为我觉得它们更清楚地传达了意图


此外,在类层次结构中,如果
类a
是抽象的并且包含抽象方法,则不需要在扩展
类a
类B
中定义该方法。在这种情况下,
类B
被标记为抽象,并且没有抽象成员。

有一个非常有用的理由可以让抽象类没有抽象方法:为可重写的方法提供默认实现。

JDK本身有几个完美的例子。例如,看一个例子。它实现接口(除其他外),但提供空的不做任何事情方法实现。在大多数情况下,您希望注册一个只覆盖一个或两个接口方法的窗口侦听器。然后您自己的类只是扩展
WindowAdapter
,而不是实现
WindowListener


请注意,对于接口中的Java 8默认方法,这一理由不再成立,事实上,没有抽象方法的抽象类不再有意义。

有一个非常有用的理由可以让抽象类没有抽象方法:为可重写方法提供默认实现。

JDK本身有几个完美的例子。例如,看一个例子。它实现接口(除其他外),但提供空的不做任何事情方法实现。在大多数情况下,您希望注册一个只覆盖一个或两个接口方法的窗口侦听器。然后您自己的类只是扩展
WindowAdapter
,而不是实现
WindowListener

注意,使用Java8默认