📜  Java |继承|问题8(1)

📅  最后修改于: 2023-12-03 15:15:58.440000             🧑  作者: Mango

Java继承问题8

在Java中,继承是面向对象编程的重要特性之一。通过继承,一个类可以继承另一个类的属性和方法,从而可以在不改变原有代码的前提下,方便地增加新的功能。

然而,在使用继承时,也可能会遇到一些问题。下面我们来看看Java继承问题8。

问题描述

假如我们有如下的两个类:

public class Parent {
    public void print() {
        System.out.println("Parent");
    }
}

public class Child extends Parent {
    public void print() {
        System.out.println("Child");
    }
}

现在我们定义一个函数:

public static void execPrint(Parent p) {
    p.print();
}

我们分别用Parent类的实例和Child类的实例调用该函数:

public static void main(String[] args) {
    Parent p = new Parent();
    Child c = new Child();

    execPrint(p);
    execPrint(c);
}

请问,该程序的输出结果是什么?

问题分析

由于Child类继承自Parent类,并且Child类中重写了Parent类中的print()方法,因此我们期望输出结果应该是:

Parent
Child

但事实上,程序的输出结果却是:

Parent
Parent

原因是因为在Java中,方法的调用是基于对象的而不是基于变量的。也就是说,当我们在父类中定义了一个方法,而该方法在子类中被重写时,当我们通过父类的引用调用该方法时,实际上调用的是子类中重写后的方法。然而,当我们通过子类的引用调用该方法时,调用的也是子类中重写后的方法。

因此,在上述代码中,虽然execPrint()函数的参数类型是Parent,但是当我们传入Child类的实例时,实际上调用的仍然是Child类中重写后的print()方法。而Child类中的print()方法中,由于没有使用super关键字调用父类中的print()方法,因此并没有执行父类中的print()方法。

解决方法

如果想要保证在父类引用调用子类对象时,能够正确地调用子类中重写后的方法,可以使用super关键字显式地调用父类中的方法。修改Child类中的代码如下:

public class Child extends Parent {
    public void print() {
        super.print();
        System.out.println("Child");
    }
}

这样一来,当我们用Parent类的引用调用Child类的实例时,首先会执行Parent类中的print()方法,然后才会执行Child类中的print()方法。因此,我们的程序输出结果就变成了:

Parent
Child
总结

在Java中,当一个类继承自另一个类时,在重写父类方法的同时,需要考虑到方法调用基于对象的这一特性。如果希望在父类引用调用子类对象时,仍然能够正确地调用子类中重写后的方法,可以使用super关键字显式地调用父类中的方法。