java可以在其他对象中调用父覆盖的方法而不是子类型吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1032847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can java call parent overridden method in other objects but not subtype?
提问by sting
here is working java code
这是工作的java代码
class Cup {
public String sayColor() {
return "i have a color .";
}
}
class TCup extends Cup{
public String sayColor(){
System.out.println(super.getClass().getName());
return super.sayColor()+"color is tee green.";
}
}
class MyTCup extends TCup {
public String sayColor(){
System.out.println(super.getClass().getName());
return super.sayColor()+"but brushed to red now!";
}
}
class Test {
public static void main(String[] args) {
Cup c = new MyTCup();
System.out.print(c.sayColor());
}
}
and running the Test class prints
并运行测试类打印
MyTCup
MyTCup
i have a color .color is tee green.but brushed to red now!
question 1: At the runtime, the type of object C is MyTCup, but it can always call the super method. Is there a method stack in the memory within MyTCup after initializing the object, and then can call through at runtime like the code ?
问题1:在运行时,对象C的类型是MyTCup,但始终可以调用super方法。初始化对象后MyTCup内存中是否有方法栈,然后可以像代码一样在运行时调用?
question 2: There is no way to call the super method in other objects. As I know ,c++ can cast to call parent method at any time. Why is it different in Java?
问题2:没有办法在其他对象中调用super方法。据我所知,C++ 可以随时转换为调用父方法。为什么它在Java中不同?
采纳答案by Jon Skeet
You can't call the super method in other objects - that would violate encapsulation. The whole point is that the object controls what its overridden methods do. For instance, you might override a collection's add
method to throw an exception in certain circumstances, so it could ensure only "valid" items got added to the collection. That would be pointless if callers could just bypass it with a cast!
您不能在其他对象中调用 super 方法 - 这会违反封装。重点是对象控制其重写方法的作用。例如,add
在某些情况下,您可能会覆盖集合的方法以引发异常,因此它可以确保仅将“有效”项添加到集合中。如果调用者可以通过演员表绕过它,那将毫无意义!
The only reason an object gets to call super.foo()
for itself is to enable one call to be implemented by using the parent implementation. It's up to the code in the class to make sure it only ever does that sensibly. Again, to take the add-in-a-collection example, if the collection overrides add
it would have to have someway of adding the validated item to the collection, which it would do with super.add()
.
对象调用super.foo()
自身的唯一原因是通过使用父实现来实现一个调用。这取决于类中的代码来确保它只明智地做到这一点。同样,以插件集合为例,如果集合覆盖,add
它必须有某种方式将经过验证的项目添加到集合中,这将使用super.add()
.
Note that for the same reason of encapuslation, you can onlycall your parent implementation, not the grandparent implementation - so super.foo()
is valid, but super.super.foo()
isn't.
请注意,出于封装的相同原因,您只能调用父实现,而不能调用祖父实现 - 所以super.foo()
是有效的,但super.super.foo()
不是。
回答by sleske
1:
1:
Your question is not quite clear. What do you mean by "call through at runtime like the code"? If you are asking how instance c knows what its super class is, then yes, the class hierarchy is stored in memory, and can be accessed by the VM.
你的问题不是很清楚。“像代码一样在运行时调用”是什么意思?如果你问实例 c 如何知道它的超类是什么,那么是的,类层次结构存储在内存中,并且可以被 VM 访问。
2:
2:
Java actually does allow you to cast an instance to its parent. It's just that calling a method on an instance always uses the instance's actual class, not its compile-time class. I.e. in Java all methods are what would be called "virtual" in C++. Why this was decided I do not know.
Java 实际上确实允许您将实例转换为其父实例。只是在实例上调用方法总是使用实例的实际类,而不是它的编译时类。即在 Java 中,所有方法在 C++ 中都称为“虚拟”。为什么会这样决定我不知道。
Edit:Actually Jon Skeet explains very nicely why you cannot call a method of a super class on an instance of a sub class, so now I know :-).
编辑:实际上,Jon Skeet 很好地解释了为什么不能在子类的实例上调用超类的方法,所以现在我知道了:-)。
回答by rogerdpack
You can define a new helper method in the subclass so that you don't override the original--call that--it can call the super method or not, depending on what you want.
你可以在子类中定义一个新的辅助方法,这样你就不会覆盖原始方法——调用它——它可以调用或不调用超级方法,这取决于你想要什么。
回答by Aquarius Power
Actually you can, but you have to use a methodology, so it will only work on your code.
At the super class, add the parameter "Class" to the method, like in:
实际上你可以,但你必须使用一种方法论,所以它只对你的代码有效。
在超类中,将参数“Class”添加到方法中,例如:
public String sayColor(Class classFilter){...
now, at every override, you check to see if the current sub-class is the one of the specified filter like:
现在,在每次覆盖时,您都会检查当前子类是否是指定的过滤器之一,例如:
if(TCup.class!=classFilter)return super.sayColor(classFilter);
return "some text for TCup only";
I coded in a exclusive way. You can add more parameters, or compare with null, so you can join results with the super classes, use your creativity :)
我以独特的方式编码。您可以添加更多参数,或与 null 进行比较,这样您就可以将结果与超类连接起来,发挥您的创造力:)