您能否举例说明为什么 Java 抽象方法不能存在于非抽象 class 中?
Can you give an example of why exactly a Java abstract method cannot exist in a non-abstract class?
我想要一个真实世界的类型示例来说明为什么 Java 抽象方法不能存在于非抽象 class.
中
我明白这不可能发生的原因 - 抽象 classes 强制执行其中包含的任何抽象方法 - 但一个可理解的具体示例确实可以帮助我在脑海中推理出来,很多谢谢。
一个抽象class意味着class不能被直接实例化。如果 class 有一个抽象方法,那么就不能直接实例化它,因为该方法没有定义。因此,任何具有抽象方法的 class 都是无法实例化的抽象 class。 Java 只是让你这样标记它。
抽象 class 和非抽象 class 之间的主要区别之一是您无法创建抽象 class 的实例。这可以防止调用没有定义的方法的情况。
所以如果我们有以下摘要class:
abstract class Elephant { // abstract class
public String getName() {
return "Ollie";
}
public abstract void walk(); // abstract method
}
那么以下是非法的:
Elephant e = new Elephant(); // error
因为Elephant
是抽象的,无法实例化。
但是为了论证,我们把Elephant
设为非抽象,但允许仍然有抽象方法walk()
。即我们将 Elephant
的定义更改为:
class Elephant { // non-abstract class
public String getName() {
return "Ollie";
}
public abstract void walk(); // abstract method
}
现在如果我执行以下操作会发生什么:
Elephant e = new Elephant(); // legal since Elephant is non-abstract
e.walk(); // oops, we didn't define this anywhere
Java 编译器不允许这样做。您可能会争辩说还有其他方法可以处理这种情况,但这只是 Java 语言决定实现该功能的方式。
就像 class
中的 abstract
方法一样,interface
中的方法(隐式抽象)允许对抽象进行建模。与多种类型相关的东西,但每个部分的行为都不同。
考虑一辆简单的车辆,它可以 drive()
,这是车辆的共同点。
public interface Vehicle {
void drive();
}
现在,您无法单独创建 Vehicle
:Vehicle v = new Vehicle()
。考虑 构建可以驱动 的东西的任务。你只关心它能不能驱动,而不管它做得有多精确。你谈论 抽象,但你总是 需要一个具体的实现,一些实际上能够做到的东西。这就是为什么你不能实例化一个抽象 class。它不完整,缺少一些抽象的必需部分。
因此,每辆车的驾驶方式都不同,如以下实施所示:
public class Car implements Vehicle {
public void drive() {
if(isEngineTurnedOn()) {
GearState state = getCurrentGearState();
if(state == GearState.BACKWARDS) {
// ...
} else {
engine.setSpeed(currentSpeed);
}
// ...
}
}
}
public class Boat implements Vehicle {
public void drive() {
if(isEngineTurnedOn()) {
rotor.setAngleInDegrees(currentAngle);
rotor.setSpeed(currentSpeed);
// ...
}
// ...
}
}
然后,如果您再次询问可以驱动的东西,您可以给来电者一个new Car()
,它有能力这样做。由于来电者只对 drive()
感兴趣,您也可以将 new Boat()
递给他。
另一种看待这个问题的方式“为什么我必须提供我的接口的实现?”
答案是因为接口方法是隐式的abstract
。因此,您必须 提供一个实现(或空体)。否则,你会得到一个编译器错误,因为没有方法体,因此没有合法的方法可以调用(JVM 不知道如何处理它 - 对于非 void return 类型,它会做什么?)。
现在,如果您将 class 声明为抽象,则不需要实现。
然后你就回到了你之前的问题,答案是一样的。无法调用抽象方法,因此允许实例化包含它们的 classes 是没有意义的。
前言:我试图让它简单和合乎逻辑,但这可能不是一个完全合乎逻辑的解释,但这肯定会帮助你在脑海中推理出来,只要知道是你必须遵守的规则。在每一种语言中,您都可能会遇到这样的规则,这些规则看起来有点混乱、有问题。
让我们试着这样理解它:
没有定义的方法是不完整的,在非抽象(完整)方法中使用抽象(不完整)方法class会增加class的不完整性,并使class 不完整。现在你不能实例化 class 因为它是不完整的(抽象的)。
这没有意义,因为你可以为此使用抽象 class,为什么要把非抽象 class 变成抽象。这就是不允许这样做的原因。
但是如果你想做这样的事情,你可以将空定义的方法添加到非抽象class.
我想要一个真实世界的类型示例来说明为什么 Java 抽象方法不能存在于非抽象 class.
中我明白这不可能发生的原因 - 抽象 classes 强制执行其中包含的任何抽象方法 - 但一个可理解的具体示例确实可以帮助我在脑海中推理出来,很多谢谢。
一个抽象class意味着class不能被直接实例化。如果 class 有一个抽象方法,那么就不能直接实例化它,因为该方法没有定义。因此,任何具有抽象方法的 class 都是无法实例化的抽象 class。 Java 只是让你这样标记它。
抽象 class 和非抽象 class 之间的主要区别之一是您无法创建抽象 class 的实例。这可以防止调用没有定义的方法的情况。
所以如果我们有以下摘要class:
abstract class Elephant { // abstract class
public String getName() {
return "Ollie";
}
public abstract void walk(); // abstract method
}
那么以下是非法的:
Elephant e = new Elephant(); // error
因为Elephant
是抽象的,无法实例化。
但是为了论证,我们把Elephant
设为非抽象,但允许仍然有抽象方法walk()
。即我们将 Elephant
的定义更改为:
class Elephant { // non-abstract class
public String getName() {
return "Ollie";
}
public abstract void walk(); // abstract method
}
现在如果我执行以下操作会发生什么:
Elephant e = new Elephant(); // legal since Elephant is non-abstract
e.walk(); // oops, we didn't define this anywhere
Java 编译器不允许这样做。您可能会争辩说还有其他方法可以处理这种情况,但这只是 Java 语言决定实现该功能的方式。
就像 class
中的 abstract
方法一样,interface
中的方法(隐式抽象)允许对抽象进行建模。与多种类型相关的东西,但每个部分的行为都不同。
考虑一辆简单的车辆,它可以 drive()
,这是车辆的共同点。
public interface Vehicle {
void drive();
}
现在,您无法单独创建 Vehicle
:Vehicle v = new Vehicle()
。考虑 构建可以驱动 的东西的任务。你只关心它能不能驱动,而不管它做得有多精确。你谈论 抽象,但你总是 需要一个具体的实现,一些实际上能够做到的东西。这就是为什么你不能实例化一个抽象 class。它不完整,缺少一些抽象的必需部分。
因此,每辆车的驾驶方式都不同,如以下实施所示:
public class Car implements Vehicle {
public void drive() {
if(isEngineTurnedOn()) {
GearState state = getCurrentGearState();
if(state == GearState.BACKWARDS) {
// ...
} else {
engine.setSpeed(currentSpeed);
}
// ...
}
}
}
public class Boat implements Vehicle {
public void drive() {
if(isEngineTurnedOn()) {
rotor.setAngleInDegrees(currentAngle);
rotor.setSpeed(currentSpeed);
// ...
}
// ...
}
}
然后,如果您再次询问可以驱动的东西,您可以给来电者一个new Car()
,它有能力这样做。由于来电者只对 drive()
感兴趣,您也可以将 new Boat()
递给他。
另一种看待这个问题的方式“为什么我必须提供我的接口的实现?”
答案是因为接口方法是隐式的abstract
。因此,您必须 提供一个实现(或空体)。否则,你会得到一个编译器错误,因为没有方法体,因此没有合法的方法可以调用(JVM 不知道如何处理它 - 对于非 void return 类型,它会做什么?)。
现在,如果您将 class 声明为抽象,则不需要实现。 然后你就回到了你之前的问题,答案是一样的。无法调用抽象方法,因此允许实例化包含它们的 classes 是没有意义的。
前言:我试图让它简单和合乎逻辑,但这可能不是一个完全合乎逻辑的解释,但这肯定会帮助你在脑海中推理出来,只要知道是你必须遵守的规则。在每一种语言中,您都可能会遇到这样的规则,这些规则看起来有点混乱、有问题。
让我们试着这样理解它:
没有定义的方法是不完整的,在非抽象(完整)方法中使用抽象(不完整)方法class会增加class的不完整性,并使class 不完整。现在你不能实例化 class 因为它是不完整的(抽象的)。
这没有意义,因为你可以为此使用抽象 class,为什么要把非抽象 class 变成抽象。这就是不允许这样做的原因。
但是如果你想做这样的事情,你可以将空定义的方法添加到非抽象class.