【问题标题】:Can you give an example of why exactly a Java abstract method cannot exist in a non-abstract class? [closed]你能举一个例子说明为什么一个Java抽象方法不能存在于一个非抽象类中吗? [关闭]
【发布时间】:2020-12-04 15:25:50
【问题描述】:

我想要一个真实的类型示例来说明为什么 Java 抽象方法不能存在于非抽象类中。

我很欣赏这不可能发生的原因 - 抽象类强制实现其中包含的任何抽象方法 - 但是一个可以理解的具体示例真的可以帮助我在脑海中推理出来,非常感谢。

【问题讨论】:

  • 为什么这不能发生?因为这是不允许的。我不确定一个例子会对你有什么帮助。
  • 有抽象类和非抽象类。非抽象类不能有抽象方法。你需要一个抽象方法 => 你需要一个抽象类。

标签: java abstract-class abstract-methods


【解决方案1】:

抽象类意味着该类不能直接实例化。如果一个类有一个抽象方法,那么它就不能直接实例化,因为该方法没有定义。因此,任何具有抽象方法的类都是无法实例化的抽象类。 Java 只是让你这样标记它。

【讨论】:

    【解决方案2】:

    抽象类和非抽象类之间的主要区别之一是您不能创建抽象类的实例。这可以防止调用没有定义的方法的情况。

    如果我们有以下抽象类:

    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 语言决定实现该功能的方式。

    【讨论】:

    • 非常感谢,您已经完全按照我的要求回答了这个问题 :) 这对我帮助很大!干杯
    【解决方案3】:

    就像class 中的abstract 方法一样,来自interface 的方法(隐式抽象)允许对抽象进行建模。与多种类型相关的东西,但每个部分的作用都不同。

    考虑一个简单的车辆,它可以drive(),这是车辆的共同点。

    public interface Vehicle {
        void drive();
    }
    

    现在,您无法单独创建VehicleVehicle v = new Vehicle()。考虑构建可以驱动的东西的任务。您只关心它可以驱动,与它的完成程度无关。你谈论一个抽象,但你总是需要一个具体的实现,实际上有能力这样做的东西。这就是为什么你不能实例化一个抽象类。它不完整,缺少一些抽象的必需部分。

    因此,每辆车的行驶方式都不同,如以下实施所示:

    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()

    【讨论】:

      【解决方案4】:

      另一种看待“为什么我必须提供我的接口的实现?”的方式

      答案是因为接口方法隐含abstract。所以你必须提供一个实现(或一个空的主体)。否则,你会得到一个编译器错误,因为没有方法体,因此没有合法的方法可以调用(JVM 不知道如何处理它 - 对于非 void 返回类型,它会做什么?)。

      现在,如果您将同一个类声明为抽象类,则不需要实现。 然后你被简化为你之前的问题,答案是相同的。抽象方法不能被调用,所以允许实例化包含它们的类是没有意义的。

      【讨论】:

        【解决方案5】:

        前言:我试图让它简单而合乎逻辑,但这可能不是一个精确的逻辑解释,但这肯定会帮助你在脑海中推理,只要知道你有一些规则跟随。在每一种语言中,您都可能会遇到这样的规则,这些规则似乎并不令人困惑、有问题。

        让我们试着这样理解它:

        没有定义的方法是不完整的,在非抽象(完整)类中使用抽象(不完整)方法会增加该类的不完整性并使该类不完整。现在您无法实例化该类,因为它不完整(抽象)。

        这没有意义,因为您可以为此使用抽象类,为什么要将非抽象类变成抽象类。这就是为什么它是不允许的。

        但是如果你想做这样的事情,你可以将具有 empty 定义的方法添加到非抽象类中。

        【讨论】:

          猜你喜欢
          • 2011-12-30
          • 2014-03-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多