是否可以在 Java 中使方法成为非虚拟方法?
Is it possible to make methods non-virtual in Java?
我是 java 的新手,我通常使用 C++ 我只是想知道这段代码是否有效
public class ParentClass {
public void methodA() {
System.out.println("This is Parent A Method");
whoAmI();
}
public void methodB() {
System.out.println("This is Parent B Method and I am Calling Method A");
whoAmI();
methodA();
}
}
public class ChildClass extends ParentClass{
@Override
public void methodA() {
System.out.println("This is Child A Method and I am Calling Parents Method A");
whoAmI();
super.methodA();
}
@Override
public void methodB() {
System.out.println("This is Child B Method and I am Calling Parents Method B");
whoAmI();
super.methodB();
}
}
ChildClass c = new ChildClass();
c.methodB();
我期望这样的输出
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
但是
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Child A Method and I am Calling Parents Method A
This is Parent A Method
所以我意识到在java中,所有非静态方法默认都是虚函数,比如c++中的virtual关键字。
有什么办法可以这样输出吗?
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
您可以将 methodA
的 ParentClass
实现包装在单独的私有方法中:
public class ParentClass {
public void methodA() {
interMethodA();
}
private void interMethodA() {
System.out.println("This is Parent A Method");
whoAmI();
}
public void methodB() {
System.out.println("This is Parent B Method and I am Calling Method A");
whoAmI();
interMethodA();
}
}
而 ChildClass
保持不变。
代码 - 按原样 - 无法编译,因为方法 whoAmI()
未定义。通过删除对此方法的调用,I was able to reproduce the output.
据我了解,您想确保 Parent
中的 methodA
是从 Parent
中的 methodB
调用的。由于在 Jjava 中使用 dynamic dispatching 来确定调用哪个实际实现,因此我们必须强制执行 methodA
不能被覆盖。正如@MarquisofLorne 指出的那样,如果 methodA
在 Parent
.
中定义为 virtual
,则 C++ 也使用动态调度
为了强制执行动态调度总是导致调用 Parent
的 methodA
,我想到了两种通用方法:将 methodA
声明为 final
并将 methodA
声明为 private
.
方法一:将 Parent
中的 methodA
声明为 final
沿着这条路线走时,Child
不能 re-define methodA
,即如果不删除 methodA
,代码将导致 compile-time 错误来自 Child
.
方法二:将 Parent
中的 methodA
声明为 private
此方法类似于第一种方法,但允许您在 Child
中保留 methodA
,尽管必须删除 @Override
-注释,因为无法覆盖私有方法。
你得到了:
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Child A Method and I am Calling Parents Method A
This is Parent A Method
而不是
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
只是因为,在 Java 中调用 methodA()
或 this.methodA()
在 ParentClass
的 methodB()
中调用调用对象或实例的方法,然而这个实例是一个 instanceof ChildClass
。 Java 将 methodA()
和 this.methodA()
视为相同。 Java 中的 this
关键字实际上指的是“您正在使用的对象的当前 运行 实例”。意思是,将调用 ChildClass 的覆盖 methodA()
而不是 ParentClass 的 methodA()
。
这里有一个建议,要获得预期的输出,只需通过注释掉打印行来对 ChildClass
的覆盖 methodA()
进行修改。
否则参考 this 了解更多详情。
我是 java 的新手,我通常使用 C++ 我只是想知道这段代码是否有效
public class ParentClass {
public void methodA() {
System.out.println("This is Parent A Method");
whoAmI();
}
public void methodB() {
System.out.println("This is Parent B Method and I am Calling Method A");
whoAmI();
methodA();
}
}
public class ChildClass extends ParentClass{
@Override
public void methodA() {
System.out.println("This is Child A Method and I am Calling Parents Method A");
whoAmI();
super.methodA();
}
@Override
public void methodB() {
System.out.println("This is Child B Method and I am Calling Parents Method B");
whoAmI();
super.methodB();
}
}
ChildClass c = new ChildClass();
c.methodB();
我期望这样的输出
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
但是
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Child A Method and I am Calling Parents Method A
This is Parent A Method
所以我意识到在java中,所有非静态方法默认都是虚函数,比如c++中的virtual关键字。
有什么办法可以这样输出吗?
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
您可以将 methodA
的 ParentClass
实现包装在单独的私有方法中:
public class ParentClass {
public void methodA() {
interMethodA();
}
private void interMethodA() {
System.out.println("This is Parent A Method");
whoAmI();
}
public void methodB() {
System.out.println("This is Parent B Method and I am Calling Method A");
whoAmI();
interMethodA();
}
}
而 ChildClass
保持不变。
代码 - 按原样 - 无法编译,因为方法 whoAmI()
未定义。通过删除对此方法的调用,I was able to reproduce the output.
据我了解,您想确保 Parent
中的 methodA
是从 Parent
中的 methodB
调用的。由于在 Jjava 中使用 dynamic dispatching 来确定调用哪个实际实现,因此我们必须强制执行 methodA
不能被覆盖。正如@MarquisofLorne 指出的那样,如果 methodA
在 Parent
.
virtual
,则 C++ 也使用动态调度
为了强制执行动态调度总是导致调用 Parent
的 methodA
,我想到了两种通用方法:将 methodA
声明为 final
并将 methodA
声明为 private
.
方法一:将 Parent
中的 methodA
声明为 final
沿着这条路线走时,Child
不能 re-define methodA
,即如果不删除 methodA
,代码将导致 compile-time 错误来自 Child
.
方法二:将 Parent
中的 methodA
声明为 private
此方法类似于第一种方法,但允许您在 Child
中保留 methodA
,尽管必须删除 @Override
-注释,因为无法覆盖私有方法。
你得到了:
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Child A Method and I am Calling Parents Method A
This is Parent A Method
而不是
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
只是因为,在 Java 中调用 methodA()
或 this.methodA()
在 ParentClass
的 methodB()
中调用调用对象或实例的方法,然而这个实例是一个 instanceof ChildClass
。 Java 将 methodA()
和 this.methodA()
视为相同。 Java 中的 this
关键字实际上指的是“您正在使用的对象的当前 运行 实例”。意思是,将调用 ChildClass 的覆盖 methodA()
而不是 ParentClass 的 methodA()
。
这里有一个建议,要获得预期的输出,只需通过注释掉打印行来对 ChildClass
的覆盖 methodA()
进行修改。
否则参考 this 了解更多详情。