【问题标题】:Why does polymorphism not work with overloaded methods in Java?为什么多态性不适用于 Java 中的重载方法?
【发布时间】:2014-11-07 04:07:31
【问题描述】:

我对 Java 中方法覆盖和重载的工作原理有基本的了解。但我的问题是为什么编译器会根据参数的编译类型搜索最具体的方法?换句话说,为什么在方法重载的情况下它会根据引用的类型而不是对象的类型进行搜索?

查看下面的示例

class Base { }

class Derived extends Base { }

class Test {

    void foo(Base thing) { System.out.println("foo(Base)"); }
    void foo(Derived thing) { System.out.println("foo(Derived)"); }

    public static void main(String[] args) { 
        Test tester = new Test(); 
        Base base = new Base(); 
        tester.foo(base);// 1st call 
        base = new Derived(); 
        tester.foo(base); // 2nd call
        tester.foo(new Derived()); // 3rd call
    } 
}

实际输出

1st call: foo(Base)

2nd call: foo(Base)

3rd call: foo(Derived)

我期待的输出

1st call: foo(Base)

2nd call: foo(Derived)

3rd call: foo(Derived)

【问题讨论】:

  • 重复 [在此处插入]。重载是基于变量静态类型的编译时问题,即#1 和#2 中的Base base
  • 在这种情况下,多态性与方法有什么关系?这些方法只是打印传入的内容,或者具体来说,传入的是什么类型的对象!

标签: java polymorphism overloading


【解决方案1】:

1) 重载发生在编译时,即要定义哪个方法 执行是在编译时决定的。
2)您正在将派生类对象引用分配给基类 运行时的对象。
3)所以在编译时显然不知道哪个引用了你的 基类对象将在未来,即在运行时。
4)这就是编译器查看引用类型的原因 方法重载的情况

【讨论】:

    【解决方案2】:

    您必须记住,当您定义变量类型(例如 Bass)时,它可以存储的唯一值是自身和从自身派生的类,例如 Derived

    一旦为该变量分配了变量类型,就无法更改。

    一种思考方式:

    假设你的 Bass 类有一个它存储的字段值:

    class Bass {
    String field1;
    
    }
    

    假设您的 Derived 类存储了一个附加字段"

    class Derived extends Bass {
    String field2;
    
    }
    

    现在假设你创建了一个 bass 实例:

    Bass bass = new Base();
    

    您可以从对象中访问field1 值。

    现在你说你做了以下事情:

    bass = new Derived();
    

    您仍然可以从对象访问field1 值。 但是,您无法访问 field2 值,因为 bass 实例不存储此值。它不符合它的结构。

    我希望这可以帮助您理解为什么将变量类型设置为等于其派生类之一时,它不会更改原始变量类型。

    【讨论】:

      猜你喜欢
      • 2014-01-21
      • 1970-01-01
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 2017-04-28
      • 2017-01-10
      • 1970-01-01
      • 2011-10-26
      相关资源
      最近更新 更多