繁体   English   中英

如何在不使用 super() 的情况下访问父 class 的重写方法?

[英]How to access overridden method of parent class without using super()?

如下所示,我尝试将子类的 object 转换为其父类 class 的 object。 那进展顺利。 但是,当我尝试访问父 class 的覆盖方法时,它不会发生。 而是调用子 class 中的覆盖方法。 我知道我可以使用 super 关键字来做到这一点,但我只想知道为什么这不能通过强制转换来完成?

这是父 class:

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

这是子 class,其属性继承自父 class:

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

这是包含主要方法的 class :

public class Main {

    public static void main(String[] args) {
        Child child = new Child();
        ((Parent)child).print();
    }

}

澄清

在您的示例中, object 始终为Child 强制转换仅适用于引用变量。 这种铸造永远不会影响实际的 object。

选项

  1. 正如其他人所提到的,添加一个单独的方法,该方法将调用super.()或使用隐藏。 隐藏实际上并不是压倒一切的。

谨防隐藏的副作用

public class AccessParent {
    public static void main(String[] args) {
        Parent p = new Child();
        p.methodC();
        System.out.println(new String(new char[20]).replace("\0", "-"));
        p.methodD();
    }
}

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

    private void methodB() {
        System.out.println("Parent.methodB");
        // this will still call Child.methodA
        // a hidden method can not control the scope of overridden method
        methodA();
    }

    void methodC() {
        System.out.println("Parent.methodC");
        methodB();
    }

    void methodD() {
        System.out.println("Parent.methodD");
        // hidden method will be called
        // technically Child.methodB() is not overridden
        methodB();
    }
}

class Child extends Parent {
    @Override
    void methodA() {
        System.out.println("Child.methodA");
    }

    // this not overridden
    void methodB() {
        System.out.println("Child.methodB");
    }
}

这将 output

Parent.methodC
Parent.methodB
Child.methodA
--------------------
Parent.methodD
Parent.methodB
Child.methodA```

您不能直接从子 class 访问覆盖的方法。 您可以做的最好的事情是向您的孩子添加另一个 function,它调用父print function。

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

然后你可以像这样访问它,

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.printParent();
    }
}

覆盖是对 inheritance 赋予权重的原则。

如果您有特定的要求来按照强制转换进行操作,则该方法必须是 class 级别“静态”而不是实例级别。

你会失去真正的 inheritance 的美丽,并更多地隐藏它。 但是,在铸造方式中也可以实现相同的效果

package com.company.language;

public class InheritanceTrial {
    public static void main(String[] args) {
        Child child = new Child();
        child.print();
        ((Parent)child).print();
    }
}
class Parent {
    public static void print() {
        System.out.println("In parent");
    }
}

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

借助 java.lang.invoke.MethodHandles、java.lang.invoke.MethodHandle 和 Z93F725A07423FE1C889F448B33D21F448B33D21 F446 所以这可能有助于你的问题。

工作解决方案

public class Child extends Parent {
  public static void main(String[] args) throws Throwable {
      MethodHandle MH_Parent = MethodHandles.lookup().findSpecial(Parent.class, "print" , MethodType.methodType(void.class), Child.class);
      MH_Parent.invokeExact(new Child());
  }
    public void print() {
        System.out.println("In child");
    }
}

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

失败的解决方案

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

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

public class Main {
    public static void main(String[] args) throws Throwable {
      MethodHandle MH_Parent = MethodHandles.lookup().findSpecial(Parent.class, "print" , MethodType.methodType(void.class), Child.class);
      MH_Parent.invokeExact(new Child());
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM