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



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

这是父类:

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

这是子类,它的属性继承自父类:

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

这个类包含main方法:

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

说明

在你的例子中,对象总是Child。强制转换仅应用于引用变量。此强制转换不会影响实际对象。

项>
  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("", "-"));
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");
}
}

这将输出

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

不能直接从子类访问被重写的方法。你能做的最好的事情就是给你的孩子添加另一个函数来调用父print函数。

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();
}
}

重写是一个赋予继承权重的原则。

如果你有一个特定的要求,按照强制转换的方式行事,那么这个方法必须是类级别的&;static&;而不是实例级。

你会失去真正继承的美,而更多地隐藏它。然而,同样可以通过

方式实现。
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和java.lang.invoke.MethodType我们只能访问直接父类的方法。所以这可能对你的问题有帮助。

工作方案
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());
}
}

相关内容

最新更新