我理解在抽象类中,方法既可以是抽象的,也可以不是抽象的。但为什么我不能在“普通”非抽象类中创建抽象方法呢?
提前感谢您的任何解释!
答案 0 :(得分:29)
Abstract 方法基本上说,没有方法的实现,需要在子类中实现。但是,如果在非抽象类中有抽象方法,则可以实例化该类并获取一个对象,该对象将具有未实现的方法,您将无法使用该方法打电话。
答案 1 :(得分:3)
使用抽象方法可以防止类被实例化,从而使它成为事实上的抽象类。 Java坚持要明确声明这一事实的一致性:从技术上讲,Java编译器不需要这个额外的标记,以便根据抽象方法的存在来决定一个类是抽象的,但是因为你可能想要创建一个类抽象而不做它的任何方法都是抽象的,要求在课堂上声明是要走的路。
答案 2 :(得分:3)
让我们首先理解为什么我们需要像抽象方法这样的东西。答案很简单。我不希望我的扩展程序按原样使用我的方法,我希望它们定义自己的特定方法的行为。因为我在我的抽象类的其他方法中使用此方法。我可以在抽象类上提供/ ** java doc ** /并指出它们使用默认行为。
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。
答案 3 :(得分:1)
您确实希望调用提供实现的方法,这是编程的本质。
基于这个想法,Java规则是:
如果Java允许您在非抽象类的实例上调用方法,而没有实现,因为方法将是abstract
=> 完全没有意义。
这就是为什么Java和处理类似C#(虚方法)之类的机制的任何其他语言都会阻止在非抽象类中声明抽象方法。
答案 4 :(得分:1)
如果具体类可以有抽象方法,则无法从中创建对象。想象一下Shape
具有具体方法getColor()
和抽象方法draw()
。以抽象的方式引用是很棒的,所以有人可以告诉你“渲染形状!”:
public void render(Shape s) { ... }
但是,当您使用该引用来调用draw()
时,您希望s
引用的对象知道如何执行此操作:
s.draw();
如果允许具体类具有抽象方法,则可以实例化Shape对象,但是当您调用draw方法时,它将不知道要绘制什么!即使它知道如何说出它的颜色,位置或其他1000个东西。如果未指定100%,则它不能作为工作对象存在。
因此Java要求将这些类标记为抽象。然后你将无法使用它们来创建对象,因为它们不知道如何具体地完成你对对象所期望的100%的事情。您只能使用抽象类来引用它们。您现在可以确定只有实现了所有方法的类才会用于创建对象,并且它们的名称可能看起来也不那么抽象:
Shape shape = new Rectangle();
render(shape);
现在你可以说“渲染形状”,你编程,使用矩形参考,将知道如何draw()
。
答案 5 :(得分:0)
因为有一个抽象方法使它成为一个抽象类。推理是循环的。
答案 6 :(得分:0)
抽象方法用于将实现留给子类。如果普通类包含抽象方法,则可以为该类创建对象,并且可以像普通方法一样调用抽象方法。然后问题就会发生。这就是抽象方法应该在抽象类中(因此不能为抽象类创建对象)或接口的原因。
答案 7 :(得分:0)
简单的答案是,如果类不是抽象的(concreate类),你可以实例化该类并调用该类中的任何方法。但是假设你在非抽象类中声明了抽象方法 - 这是不可能的调用那个特定的抽象方法。(为了防止这种情况,我们不能在非抽象类中声明抽象方法)
答案 8 :(得分:0)
以另一种方式查看它,如果您将方法定义为抽象,则意味着您肯定会将该类继承到其他一个/多个类,否则就无需使用将其定义为抽象。此外,您应该将抽象方法保留在父类的类中,这些类具有可继承的成员和其他子类的特征。 因此,如果对于一个抽象方法需要继承整个类,那么我们也可以使用所需的访问说明符来定义其他变量,以便也可以根据需要继承它,因此无需创建父类的对象来调用具体成员。 / p>