【问题标题】:Superclass and subclass arguments超类和子类参数
【发布时间】:2016-04-04 11:53:14
【问题描述】:

我提供如下两个类:

家电类

public class Appliance {
    void start(Appliance t){
        System.out.println("Start Appliance");
    }
}

烤面包机班​​p>

public class Toaster extends Appliance {
    void start(Toaster t){
        System.out.println("Start Toaster");
    }
}

RunAppliance 类

public class RunAppliance {
    public static void main(String[] args) {
        Appliance appliance = new Toaster();
        Toaster toaster = new Toaster();
        appliance.start(toaster);
    }
}

作为一个新手,它让我在方法重载和覆盖之间感到困惑,以及参数如何在一种参数类型中受到影响是另一种参数类型的子类。因此,我提出了 6 个相同的条件:

1)Appliance Class : void start(Appliance t) ; 烤面包机类 : void start(Appliance t)

2)Appliance Class : void start(Toaster t) ; Toaster 类 : void start(Toaster t)

3)Appliance Class : void start(Appliance t) ; Toaster 类 : void start(Toaster t)

4)Appliance Class : void start(Toaster t) ; 烤面包机类 : void start(Appliance t))

5)Appliance Class : void start(Appliance t) & void start(Toaster t) ; Toaster 类 : void start(Toaster t)

6)Appliance Class : void start(Appliance t) ; Toaster Class : void start(Appliance t) & void start(Toaster t))

谁能给我建议一个必要的规则。

【问题讨论】:

  • 你到底在问什么?这“6 个条件”是什么?
  • 什么是必要规则?
  • 这些是具有不同参数类型的同一方法的不同版本,粗体是在上面的代码部分中调用它们的类名。
  • 必要规则是指在什么基础上可以预测输出以及如何发生重载和覆盖

标签: java inheritance polymorphism overloading overriding


【解决方案1】:

您的Toaster 课程不正确。其start() 方法的参数应该是Appliance,而不是Toaster

您的实现不符合 Liskov 替换原则。您不能在任何需要 Appliance 的地方使用 Toaster,因为它不会覆盖所写的 start() 方法。

这样做:

public class Toaster extends Appliance {
    void start(Appliance a){
        System.out.println("Start Toaster");
    }
}

【讨论】:

  • 非常感谢您的评论。所以如果我更正此错误,行为将如何根据给定的条件和哪些无效而改变。
  • 我不知道行为会如何改变,但我知道会发生什么:多态性意味着运行时 Appliance 实例在您调用它的 start() 方法时将打印“Start Appliance”;当您调用它的 start() 方法时,运行时 Toaster 实例将打印“Start Toaster”。
  • Okz.so 如果我遵循原则只有我的第一个条件是对的,其他的都是无效的??
  • 我没有读过所有的废话。没有父类可以知道子类。所有需要使用带有 Toaster 方法的 Appliance 的情况都是完全错误的。
  • 我确实帮你改正了。我告诉了你正确的答案,并指出了为什么你想象的其他五个场景是错误的。我不是你的朋友。接受正确的答案并继续前进。
【解决方案2】:

我想你是在问以下每种情况的输出:

    Appliance appliance = new Appliance();
    Appliance applianceToaster = new Toaster();
    Toaster toaster = new Toaster();
    appliance.start(appliance);
    appliance.start(toaster);
    appliance.start(applianceToaster);
    toaster.start(appliance);
    toaster.start(toaster);
    toaster.start(applianceToaster);
    applianceToaster.start(appliance);
    applianceToaster.start(toaster);
    applianceToaster.start(applianceToaster);

正如@duffymo 指出的那样,在 Toaster 启动方法中将 Toaster 更改为 Appliance。 Toaster 中的 start 将隐藏 Appliance 在运行时作为 Toaster 的任何对象的 start。您需要超级用户才能从 Toaster 中的开头访问 Appliance 中的开头。

在编译时,appliance 看起来像 Appliance,在运行时它是一个 Appliance,因此无论向其发送哪个参数,都会调用 Appliance 中的 start。

在编译时toaster看起来像Toaster,在运行时它是一个Toaster,所以无论向它发送哪个参数,都会调用Toaster中的start。

在编译时,applianceToaster 看起来像 Appliance,在运行时它是一个 Toaster,因此无论发送给它的参数如何,都会在 Toaster 中启动多态调用。

【讨论】:

    猜你喜欢
    • 2012-04-08
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    相关资源
    最近更新 更多