【问题标题】:Override beats Overload? Why does that make sense at all?覆盖节拍过载?为什么这完全有道理?
【发布时间】:2013-09-17 20:07:17
【问题描述】:

为什么超级方法应该将它的 this 引用作为超级类型而不是自己的类型分发?

我不明白这种行为的实用性。我学会了针对类型/接口而不是针对类进行编码,但是考虑到这种行为,我对我认为 OOP 所代表的一切感到困惑。这打破了干净代码的可能性,并迫使我用冗长的控制流来填充它,比如大量使用 instanceof 运算符。 为什么这种行为甚至有意义?

摘要:
考虑这段代码:

abstract class A {
    public void visit(Target t) {
         t.method(this);
    }
}

如果 Target 重载 method() 并在其签名中使用 A 和 A 的不同子类,并且这些子类本身不覆盖 visit(Target t),则编译器将始终选择重载的 method(A a)

工作示例: http://pastebin.com/EGNpY7pF

代码片段

public class Target {

public static abstract class A {
    void visit(Target t) {
        t.method(this);
    }
}

public static class B extends A {}
public static class C extends A {
    @Override
    void visit(Target t) {
        t.method(this);
    }
}

void method(A a) { System.out.println("A");}
void method(B b) { System.out.println("B");}
void method(C c) { System.out.println("C");}

public static void main(String[] args) {
    Target t = new Target();
    A ab = new B();
    B b = new B();
    A ac = new C();
    C c = new C();

    ab.visit(t);
    b.visit(t);
    ac.visit(t);
    c.visit(t);

}

}

输出 A A C C
这真的很糟糕,因为 ac 被引用为 A-Type 但仍然调用了 C 的覆盖 visit() 方法。

【问题讨论】:

  • 您能否在您的问题中发布更完整的代码 sn-p,因为您的描述有点难以理解。
  • A 中拥有该方法并不意味着实现被逐字复制到其每个子类中。任何地方都只有一份A.visit,而且那一份专门指重载t.method(A)
  • 这是您的代码,输出为ideone.com/1s14qi
  • 我明白你在说什么,路易斯·瓦瑟曼。由于在A 的访问中,它在编译时决定如果没有子类覆盖visit() 将调用method(),它是静态的而不是动态的。弱。

标签: java oop types overloading


【解决方案1】:

您的问题不清楚。当在对象的实例上调用函数时,将调用子对象的方法,即使它被引用为其父对象的类型;多态性。如果子类没有覆盖该方法,则将调用该方法的父类的实现;从层次结构继承。

如果一个类调用它自己的方法,并在其前面加上 super 前缀,它将在层次结构中找到与签名匹配的最近的实现。

【讨论】:

    猜你喜欢
    • 2011-06-18
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    相关资源
    最近更新 更多