[英]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。
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.