MST

星途 面试题库

面试题:Java多态下父类与子类方法调用优先级之复杂继承体系

给定以下Java类继承结构: class GrandParent { public void display() { System.out.println("GrandParent"); } } class Parent extends GrandParent { @Override public void display() { System.out.println("Parent"); } } class Child extends Parent { @Override public void display() { System.out.println("Child"); } } class SpecialChild extends Child { public void displaySpecial() { System.out.println("SpecialChild's special method"); } } public class Main { public static void main(String[] args) { GrandParent gp1 = new GrandParent(); GrandParent gp2 = new Parent(); GrandParent gp3 = new Child(); GrandParent gp4 = new SpecialChild(); gp1.display(); gp2.display(); gp3.display(); gp4.display(); // 如果想在这调用SpecialChild的displaySpecial方法,应该怎么做?请修改代码实现 } } 请写出程序输出结果,并阐述如何调用SpecialChild类特有的displaySpecial方法,说明涉及的多态概念。
35.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 程序输出结果
    GrandParent
    Parent
    Child
    Child
    
    解释:在Java中,方法调用遵循动态绑定机制。当通过父类引用调用重写的方法时,实际调用的是对象实际类型(运行时类型)的重写方法。gp1GrandParent类型的对象,所以调用GrandParentdisplay方法输出GrandParentgp2实际是Parent类型,gp3实际是Child类型,gp4实际是SpecialChild类型,它们都会调用各自实际类型重写的display方法。
  2. 调用SpecialChild类特有的displaySpecial方法: 由于gp4的声明类型是GrandParent,不能直接调用displaySpecial方法。需要进行向下转型,将GrandParent类型的gp4转换为SpecialChild类型,修改后的代码如下:
    public class Main {
        public static void main(String[] args) {
            GrandParent gp1 = new GrandParent();
            GrandParent gp2 = new Parent();
            GrandParent gp3 = new Child();
            GrandParent gp4 = new SpecialChild();
            gp1.display();
            gp2.display();
            gp3.display();
            gp4.display();
            if (gp4 instanceof SpecialChild) {
                SpecialChild sc = (SpecialChild) gp4;
                sc.displaySpecial();
            }
        }
    }
    
    在上述代码中,使用instanceof关键字先检查gp4是否是SpecialChild类型的实例,如果是,则进行向下转型并调用displaySpecial方法。
  3. 涉及的多态概念
    • 向上转型:代码中GrandParent gp2 = new Parent(); GrandParent gp3 = new Child(); GrandParent gp4 = new SpecialChild();这些都是向上转型,将子类对象赋值给父类引用。向上转型后,通过父类引用只能访问父类中定义的方法(除非子类重写了该方法,此时调用子类重写的方法)。
    • 动态绑定:在运行时,根据对象的实际类型来决定调用哪个类的重写方法,例如gp2.display()实际调用的是Parent类的display方法,而不是GrandParent类的display方法,这就是动态绑定机制实现的多态。
    • 向下转型:如上述代码中从GrandParent类型转换为SpecialChild类型,向下转型需要格外小心,因为如果实际对象不是目标类型,会抛出ClassCastException异常,所以通常使用instanceof关键字进行类型检查后再进行向下转型。