【问题标题】:Can java call parent overridden method in other objects but not subtype?java可以在其他对象而不是子类型中调用父覆盖方法吗?
【发布时间】:2009-06-23 14:20:08
【问题描述】:

这是工作的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());
    }
}

并运行测试类打印

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

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

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

【问题讨论】:

  • 对答案满意后,您应该接受它:)

标签: java overriding


【解决方案1】:

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

对象为自己调用super.foo() 的唯一原因是通过使用父实现来实现一个调用。这取决于类中的代码,以确保它只会明智地做到这一点。同样,以 add-in-a-collection 为例,如果集合覆盖 add,它必须有 some 方法将经过验证的项目添加到集合中,这将与 @ 987654325@.

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

【讨论】:

【解决方案2】:

1:

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

2:

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

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

【讨论】:

  • 我的意思是从 MyTCup 调用到 TCup 和 Cup 的“sayColor”方法,显示的类是“MyTCup”。所以这些方法属于 MyTCup 或属于 TCup,Cup。我不熟悉 jvm,也许都在方法区。
【解决方案3】:

你可以在子类中定义一个新的辅助方法,这样你就不会覆盖原来的——调用那个——它可以调用或不调用超级方法,这取决于你想要什么。

【讨论】:

    【解决方案4】:

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

    public String sayColor(Class classFilter){...
    

    现在,在每次覆盖时,您都会检查当前子类是否是指定过滤器之一,例如:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多