Java - 调用方法时的继承和变量类型

标签 java inheritance methods overriding invoke

我在理解某些代码的结果时遇到了一些大问题。

public class ClassA {
    public void stampa(ClassA p) {
        System.out.println("AAA");
    }
}
public class ClassB extends ClassA {
    public void stampa(ClassB p) {
        System.out.println("BBB");
    }
    public void stampa(ClassA p) {
        System.out.println("AAA/BBB");
    }
}
public class ClassC extends ClassA {
    public void stampa(ClassC p) {
        System.out.println("CCC");
    }
    public void stampa(ClassA p) {
        System.out.println("AAA/CCC");
    }
}

主要是这样的

public static void main(String[] args) {
    ClassA a1, a2;
    ClassB b1;
    ClassC c1;
    a1 = new ClassB();
    b1 = new ClassB();
    c1 = new ClassC();
    a2 = new ClassC();
    b1.stampa(b1);//BBB
    a1.stampa(b1);//AAA/BBB
    b1.stampa(c1);//AAA/BBB
    c1.stampa(c1);//CCC
    c1.stampa(a1);//AAA/CCC
    a2.stampa(c1);//AAA/CCC
}

我很难理解为什么 a1.stampa(b1); 的结果是这样的是“AAA/BBB”而不是“BBB”。 正如我从继承中了解到的,编译时 a1 的静态类型是 ClassB,所以我在 ClassB 中搜索“stampa”方法,对于方法的参数,静态类型也是 ClassB,所以我会选择第一个 stampa ClassB 的方法。

当我试图理解 a2.stampa(c1) 的结果时,同样的事情也会发生;这是“AAA/CCC”而不是“CCC”。

有人可以帮助我理解我做错了什么吗?

最佳答案

问题是下面的

public class ClassB extends ClassA {
    public void stampa(ClassB p) {

不是覆盖这个

public class ClassA {
    public void stampa(ClassA p) {

它正在重载它...

这意味着它是一个额外的方法,而不是覆盖,并且只能通过 b1.stampa(b1); 访问。

仅当您具有相同的方法签名时才会发生,但称为“协变返回”的东西除外,本质上是相同的概念,但返回类型是子类。

关于Java - 调用方法时的继承和变量类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38417809/

相关文章:

c# - 向 RESTful WCF 服务发送发布请求

java - iOS 中的事件总线等效项

java - Calendar.getInstance() 性能通过 'warm up' 调用得到改进?

Java:从父类访问子类方法

postgresql - Postgres : Performance and correctness of inheritance-foreign-key workaround

java - 如何从类的其他方法访问该方法?

java - 防止目录混淆

c++ - 如何向结构添加新成员

java - 如何访问子类中的方法

java - 使用指向派生对象的基引用调用重写方法,在运行时将调用什么?