java可以调用其他对象中的父类重写方法,但不能调用子类型吗?

发布于 2024-07-24 16:24:02 字数 922 浏览 8 评论 0原文

这是有效的 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());
    }
}

,运行 Test 类会打印

MyTCup
MyTCup
i have a color .color is tee green.but brushed to red now!

问题 1: 运行时,对象C的类型是MyTCup,但它总是可以调用super方法。 MyTCup 初始化对象后内存中是否有一个方法堆栈,然后可以像代码一样在运行时调用?

问题2: 没有办法调用其他对象中的super方法。 据我所知,c++可以随时调用父方法。 为什么在 Java 中会有所不同?

here is working java code

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 ?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦巷 2024-07-31 16:24:02

您不能在其他对象中调用 super 方法 - 这会违反封装。 重点是对象控制其重写方法的功能。 例如,您可以重写集合的 add 方法以在某些情况下引发异常,因此可以确保仅将“有效”项目添加到集合中。 如果调用者可以通过强制转换绕过它,那将毫无意义!

对象为自己调用 super.foo() 的唯一原因是通过使用父实现来实现一次调用。 由类中的代码来确保它只明智地执行此操作。 同样,以集合中的添加为例,如果集合重写了 add,则必须采用某种方式将已验证的项目添加到集合中,这它可以与 super.add() 一起使用。

请注意,出于封装的相同原因,您只能调用父实现,而不能调用祖父实现 - 因此 super.foo() 有效,但 super .super.foo() 不是。

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!

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 some way of adding the validated item to the collection, which it would do with super.add().

Note that for the same reason of encapuslation, you can only call your parent implementation, not the grandparent implementation - so super.foo() is valid, but super.super.foo() isn't.

丿*梦醉红颜 2024-07-31 16:24:02

1:

你的问题不太清楚。 “像代码一样在运行时调用”是什么意思? 如果您问实例 c 如何知道其超类是什么,那么是的,类层次结构存储在内存中,并且可以由 VM 访问。

2:

Java 实际上允许您将实例强制转换为其父实例。 只是在实例上调用方法总是使用实例的实际类,而不是其编译时类。 即,Java 中的所有方法都是 C++ 中所谓的“虚拟”方法。 我不知道为什么这样决定。

编辑:实际上 Jon Skeet 很好地解释了为什么不能在子类的实例上调用超类的方法,所以现在我知道了:-)。

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.

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.

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 :-).

暗地喜欢 2024-07-31 16:24:02

您可以在子类中定义一个新的辅助方法,这样您就不会覆盖原始方法(调用该方法),它可以调用超级方法,也可以不调用超级方法,具体取决于您想要的。

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.

不美如何 2024-07-31 16:24:02

其实你可以,但你必须使用一种方法,所以它只适用于你的代码。
在超类中,将参数“Class”添加到方法中,如下所示:

public String sayColor(Class classFilter){...

现在,在每次重写时,您检查当前子类是否是指定的过滤器之一,例如:

if(TCup.class!=classFilter)return super.sayColor(classFilter);
return "some text for TCup only";

我以独占方式编码。 您可以添加更多参数,或与 null 进行比较,这样您就可以将结果与超类连接起来,发挥您的创造力:)

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:

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 :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文