Java 为什么抽象方法只能在抽象类中声明?

Java 为什么抽象方法只能在抽象类中声明?,java,abstract-class,abstract,abstract-methods,Java,Abstract Class,Abstract,Abstract Methods,我知道在抽象类中,方法可以是抽象的,也可以不是抽象的。但是为什么我不能在一个“普通的”非抽象类中创建一个抽象方法呢 提前感谢您的解释 抽象方法基本上是说,该方法没有实现,需要在子类中实现。但是,如果在非抽象类中有一个抽象方法,则可以实例化该类并获取一个对象,该对象将有一个无法调用的未实现方法。有一个抽象方法会阻止类被实例化,从而使其成为事实上的抽象类。Java坚持要您明确声明这一事实以保持一致性:从技术上讲,Java编译器不需要这个额外的标记来根据抽象方法的存在来决定类是否是抽象的,但由于您可能

我知道在抽象类中,方法可以是抽象的,也可以不是抽象的。但是为什么我不能在一个“普通的”非抽象类中创建一个抽象方法呢


提前感谢您的解释

抽象方法基本上是说,该方法没有实现,需要在子类中实现。但是,如果在非抽象类中有一个抽象方法,则可以实例化该类并获取一个对象,该对象将有一个无法调用的未实现方法。

有一个抽象方法会阻止类被实例化,从而使其成为事实上的抽象类。Java坚持要您明确声明这一事实以保持一致性:从技术上讲,Java编译器不需要这个额外的标记来根据抽象方法的存在来决定类是否是抽象的,但由于您可能希望使类抽象而不使其任何方法抽象,需要在类上声明是一条路。

因为拥有抽象方法使其成为抽象类。推理是循环的。

您确实希望调用提供实现的方法,这是编程的本质

基于这一理念,Java规则包括:

  • 不能实例化抽象类
  • 只能实例化非抽象类
如果Java允许您在一个非抽象类的实例上调用一个方法,但没有实现,因为该方法将是
抽象的
=>毫无意义


这就是为什么Java和处理类似机制的任何其他语言(如C#(虚拟方法))都会阻止在非抽象类中声明抽象方法。

让我们从理解为什么开始我们需要类似抽象方法的东西。答案很简单。我不希望我的扩展器使用我的方法,我希望他们定义自己的特定方法行为。因为我在抽象类的其他方法中使用了这个方法。我可以在抽象类上提供一个/**java文档**/,并指示它们使用默认行为

class abstract LoveTheWorld {
    private int myKindness ;
    public int defaultGiveKindness() {
        myKindness -= 5 ;
        return 5 ;
    }
    /**
    you can use the defaultGiveKindness method, and not define your own behavior
    **/
    public abstract int giveKindness() ;
}

这还告诉扩展程序它们只能扩展一个类(根据java继承规则)。现在,如果您想扭转这个故事,您可以使用接口而不是抽象类。但这一切都取决于你希望你未来的开发者遵守什么约束,严格还是灵活严格将保持紧密,确保减少错误,灵活将保持宽松和自由,并促进创新。问题是**您需要什么*8。

抽象方法是为了将实现留给子类。如果普通类包含抽象方法,然后可以为该类创建对象,并可以像调用普通方法一样调用抽象方法。然后问题就会出现。这就是为什么抽象方法应该在抽象类中(这样就不能为抽象类创建对象)或仅接口的原因。

如果一个具体类可以有一个抽象方法,您将无法从中创建对象。想象一个
形状
,有一个具体的方法
getColor()
和一个抽象的方法
draw()
。以抽象的方式引用某些事物非常好,因此有人可以告诉您“渲染形状!”:

但是当您使用该引用调用
draw()
时,您希望
s
引用的对象知道如何执行该操作:

s.draw();
如果允许具体类具有抽象方法,您可以实例化一个Shape对象,但是当您调用draw方法时,它不知道要绘制什么!即使它知道如何说出它的颜色、位置或其他东西。如果未100%指定,则不能作为工作对象存在

因此Java要求将此类类标记为抽象类。然后你将无法使用它们来创建对象,因为它们不知道如何具体地完成你期望从对象中得到的100%的事情。您只能使用抽象类来引用它们。现在您可以确定,只有实现了所有方法的类才会用于创建对象,而且它们的名称也可能不那么抽象:

Shape shape = new Rectangle();
render(shape);

现在,您可以说“渲染形状”,然后使用对矩形的引用编程,您将知道如何
绘制()
它。

简单的答案是,如果类不是抽象的(具体类)您可以实例化该类并调用该类的任何方法,但假设您在该非抽象类中声明了一个抽象方法,则不可能调用该特定的抽象方法。(为了防止这种情况发生,我们不能在非抽象类中声明抽象方法)

从另一个角度来看,如果您将一个方法定义为抽象,这意味着您肯定要将该类继承给其他类,否则就没有必要将其定义为抽象。此外,您应该在父类中保留抽象方法,这些类具有可继承的成员以及其他子类的特征。
因此,如果一个抽象方法需要继承整个类,那么我们也可以使用所需的访问说明符定义其他变量,这样它也可以根据需要继承,因此不需要创建父类的对象来调用具体成员。

因为如果类不是抽象的,你可以创建一个作为类实例的对象,然后你可以尝试为该对象调用该方法,而该方法不存在,因为它是抽象的,然后呢?这是一个设计问题,你应该考虑需要,并改变(设计模式)。@ajb感谢你简洁的回答,清楚地说“如果会怎么样”
Shape shape = new Rectangle();
render(shape);