英文:
Is it possible to make methods non-virtual in Java?
问题
在Java中,所有非静态方法默认都是虚方法,类似于C++中的虚函数。要达到您期望的输出,可以将父类的methodA
和methodB
方法标记为final
,这样它们就不能被子类重写。这将防止子类在调用这些方法时执行它们自己的实现。以下是修改后的代码:
public class ParentClass {
public final void methodA() {
System.out.println("This is Parent A Method");
whoAmI();
}
public final 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
英文:
i am newbie in java and i usually used c++ i just wondering this code works
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();
and I expected output like this
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
but was
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
so i realized that in java all non-static methods are by default virtual functions like virtual keyword in c++.
is there any way to make output like this?
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
答案1
得分: 1
你可以将 ParentClass
的 methodA
的实现包装在一个单独的私有方法中:
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
保持不变。
英文:
You can wrap the methodA
's impl of ParentClass
in a seperate private method:
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();
}
}
And the ChildClass
remains the same.
答案2
得分: 1
代码 - 如所示 - 由于方法 whoAmI()
未定义而无法编译。通过删除对此方法的调用,我能够复制输出。
据我理解,您希望确保在 Parent
中的 methodA
从 Parent
中的 methodB
中被调用。由于在 Java 中使用了 动态分派 来确定调用哪个实际实现,我们必须强制 methodA
不能被覆盖。正如 @MarquisofLorne 所指出的,C++ 也使用了动态分派,如果在 Parent
中将 methodA
定义为 virtual
。
为了确保动态分派始终调用 Parent
的 methodA
,我想到了两种常见的方法:将 methodA
声明为 final
和将 methodA
声明为 private
。
方法一:将 Parent
中的 methodA
声明为 final
选择这种方法时,Child
无法重新定义 methodA
,即如果不从 Child
中删除 methodA
,则代码将导致编译时错误。
方法二:将 Parent
中的 methodA
声明为 private
这种方法类似于第一种方法,但允许您在 Child
中保留 methodA
,尽管必须删除 @Override
注解,因为私有方法无法被覆盖。
英文:
The code - as is - does not compile since method whoAmI()
is undefined. By removing the calls to this method, I was able to reproduce the output.
From what I understand, you want to ensure that methodA
in Parent
is called from methodB
in Parent
. Since dynamic dispatching is used in Jjava to determine which actual implementation is called, we have to enforce that methodA
cannot be overridden. As @MarquisofLorne pointed out, C++ uses dynamic dispatch aswell, if methodA
is defined as virtual
in Parent
.
To enforce that dynamic dispatch always results in a call to Parent
's methodA
, there are two general approaches that come to my mind: declaring methodA
as final
and declaring methodA
as private
.
Approach one: declare methodA
in Parent
as final
When going down this route, Child
cannot re-define methodA
, i.e. the code would result in a compile-time error if methodA
is not removed from Child
.
Approach two: declare methodA
in Parent
as private
This approach is similar to the first approach, but allows you to retain methodA
in Child
, albeit the @Override
-annotation must be removed since private methods cannot be overridden.
答案3
得分: 0
这是Child B方法,我正在调用Parent方法B
这是Parent方法B,我正在调用方法A
这是Child A方法,我正在调用Parent方法A
这是Parent方法A
英文:
You got:
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
Instead of
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
Simply Bacause, In Java calling methodA()
or this.methodA()
in your methodB()
of ParentClass
calls the method off of the calling object or instance, Yet the instance is an instanceof ChildClass
. Java treats methodA()
and this.methodA()
as same. The this
keyword in Java actually refers to the "currently running instance of the object you're using". Meaning, the overridding methodA()
of ChildClass will be called instead of methodA()
of ParentClass.
Here is a suggestion, to get the expected output, simply apply modifications on the overridding methodA()
of ChildClass
by commenting out the printing line.
Otherwise reference this for more details.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论