繁体   English   中英

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

[英]Can java call parent overridden method in other objects but not subtype?

这是工作的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不同?

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

对象为自己调用super.foo()的唯一原因是通过使用父实现来启用一个调用。 这取决于班级中的代码,以确保它只能做到明智。 再次,要采用加法收集示例,如果集合覆盖add则必须有一些方法将验证的项目添加到集合中,这将与super.add()

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

1:

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

2:

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

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

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

public String sayColor(Class classFilter){...

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

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

我以独家方式编码。 你可以添加更多参数,或者与null比较,这样你就可以加入超类的结果,使用你的创造力:)

你可以在子类中定义一个新的辅助方法,这样就不会覆盖原来的 - 调用它 - 它可以调用super方法,具体取决于你想要的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM